Skip to content

Take out Object#among? but add in Object#ex? - #265

Closed
sikachu wants to merge 1 commit into
rails:masterfrom
sikachu:among_out_ex_in
Closed

Take out Object#among? but add in Object#ex?#265
sikachu wants to merge 1 commit into
rails:masterfrom
sikachu:among_out_ex_in

Conversation

@sikachu

@sikachu sikachu commented Apr 12, 2011

Copy link
Copy Markdown
Member

After a very long discussion on #258 and discussion with @dhh, we've decide that we want to do two things to it.

1. Remove Object#among?

The reason for removal would be because these three things:

  1. Performance problem. Using varargs here seems to bug a lot of people
  2. It's shorter; obj.in?([1,2,3]) is wayyyyy shorter than obj.among?(1,2,3)
  3. No good name for the inverse of it.

If you really want obj.among?, please show us your support by saying so and suggest a good name for inverse of it.

2. Add Object#ex?

A while ago, @pigoz has come up with this wonderful name from Latin. We think it fits with #in nicely, so we're including it here. You could say that "#ex? is the new #not_in?`

Feedback needed!

Please keep the awesome discussion going. Make a comment if you like it/hate it.

@phene

phene commented Apr 12, 2011

Copy link
Copy Markdown

-1 for Object#ex?

Not only does 'ex' mean "out of," it also means "from" and implies that it was once in the list.

ex-pirate = Once a pirate, but no longer a pirate.

option.ex?(:foo, :bar) # Was once :foo or :bar, but no longer is?

There's too much linguistic baggage to be repurposed this way.

@ches

ches commented Apr 12, 2011

Copy link
Copy Markdown

+1 on removing #among?. I liked #either better for its symmetry with #neither (indeed the fact that that works so well is what kicked off this whole mess of finding something equally nice for not_in?), and as it stands I'm fairly certain I would always prefer writing obj.in?([1,2,3]) to obj.among?(1, 2, 3). Not to re-open the debate but FWIW I had no problem with either/neither for more than two alternatives -- I personally consider e.g. "we can do either this, that, or nothing at all" perfectly natural speech.

I'm also with @phene on -1 for #ex? being unclear. For me the first Latin phrase that comes to mind is deus ex machina -- "god from the machine," which doesn't help me in the slightest to recall the semantics of this method. As he points out the meaning of "ex" as "formerly" further clouds things too.

@dtrasbo

dtrasbo commented Apr 12, 2011

Copy link
Copy Markdown
Contributor

I suggest using another Latin word: "sans". It was suggested in the previous pull request and I think it's worth reconsidering. 1) It's short 2) It's precise 3) The community knows what it means - e.g. sans-serif means a font without serifs.

@ernie

ernie commented Apr 12, 2011

Copy link
Copy Markdown
Contributor

Object#in? is nice, and adds expressivity. As for the rest of them, I made the comment on #258, but I think it remains relevant to the discussion on #ex?:

This discussion is like TDD for syntax, and I think the tests are telling us something.

in? Feels pretty natural, and is handy in the same way blank? and present? are. All of the rest just feel wrong.

I think this is because we're trying to solve a nonexistent problem. Someone mentioned earlier how the English language doesn't really have clear one-word negation options here. That's because in English, we would say "3 is not in the set of 1, 2, 4".

I think this tells us something, given that only real use for this method is in conditionals, to begin with (including the ternary operator). The rest aren't needed.

Where we ask "if object.in?(array)", the opposite is "unless object.in?(array)". If necessary, !object.in?(array) feels pretty natural as well.

This seems obvious, as we discuss this. blank? was handy given ruby's definition of truthiness, but present? was a welcome addition because negating a "negative" (!blank?) method like blank was often less expressive of intent. You don't ask "is that space still blank?" as often as you ask "has it been filled in?"

Since the English idiom here is to say "not in", I think the standard Ruby idioms for negating the condition already complement in? nicely.

@phene

phene commented Apr 12, 2011

Copy link
Copy Markdown

I like sans, but the object-subject order doesn't fit for this scenario.

items.sans? kitchen_sink

makes a lot more sense than

kitchen_sink.sans? items

@bayan

bayan commented Apr 13, 2011

Copy link
Copy Markdown

I don't understand why are we jumping through so many hoops to avoid using "not in"?

Is it really that bad? Is it really so bad that we have to leave the English language entirely to find an alternative?!

I know some people find it ugly, but to me, it reads exactly as it should work. With most of the other suggestions, I have do a small mental conversion back to "not in".

It's also the most obvious - I wouldn't need to bother looking up documentation if I ever came across this code in use.

not_in? just seems more self documenting, just like exclude?, present?, etc.

ex? and sans? are not so obvious without the help of an explanation or documentation to justify their use.

The only caveat, which I somewhat agree with, is that we already have the negation operators '!' and 'not' that already does this. But like much of ruby (and rails) there's more than one way to skin a cat.

@sikachu

sikachu commented Apr 13, 2011

Copy link
Copy Markdown
Member Author

This is my proposal for #among?:

  • alias :either?, :among?
  • Add #neither? as a opposite.

So in some context which you test against two items, you might consider #either? to be more fit on it. While for testing on 3 things or more you'd use #among? because it reads better instead.

For #neither?, the word actually means "not the one nor the other of two people or things" so I think it's a good fit. In the real english it's ok for you to have more than 2 items such as:

I'm neither tenderlove, DHH, nor josevalim.

@arthurschreiber

Copy link
Copy Markdown
Contributor

+1 for removing Object#among?/Object#either?
+1 for ernie's suggestion (so -1 for adding Object#ex?). We need no inverse for Object#in?, as we can simply use !/not/unless, as in:

unless my_object.in?(["a", "b", "c"])
 ...
end

or

if my_object.in?(["a", "b"]) and not my_object.in?(["c", "d"])
  ...
end

@dhh

dhh commented Apr 13, 2011

Copy link
Copy Markdown
Member

Seeing ex? in usage here, I'm falling out of favor too. Let's just start small, we don't need to solve everything now. The big win is just to get Object#in? -- we can think deeper about the perfect opposite some other time.

@sikachu, please rebase one last time with only Object#in? being part of the game and we'll move on from this for now.

@sikachu

sikachu commented Apr 13, 2011

Copy link
Copy Markdown
Member Author

Will do.

Sent from my iPhone

On 13 เม.ย. 2554, at 16:11, [email protected] wrote:

Seeing ex? in usage here, I'm falling out of favor too. Let's just start small, we don't need to solve everything now. The big win is just to get Object#in? -- we can think deeper about the perfect opposite some other time.

@sikachu, please rebase one last time with only Object#in? being part of the game and we'll move on from this for now.

Reply to this email directly or view it on GitHub:
#265 (comment)

@sikachu

sikachu commented Apr 13, 2011

Copy link
Copy Markdown
Member Author

The pull request has been updated with one commit only.

After a long list of discussion about the performance problem from using varargs and the reason that we can't find a great pair for it, it would be best to remove support for it for now.

It will come back if we can find a good pair for it. For now, Bon Voyage, `#among?`.
@sikachu

sikachu commented Apr 13, 2011

Copy link
Copy Markdown
Member Author

This pull request has been merged and shall now be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants