top | item 11106911

An 'in' operator for Ruby

88 points| charlieegan3 | 10 years ago |rubyhacker.com | reply

62 comments

order
[+] tyre|10 years ago|reply
Rails implements this as `in?`

https://github.com/rails/rails/blob/d61baee52adcd1baebe15f10...

You're welcome to try and merge that into Ruby core itself. That said, "I like whitespace" isn't a good reason to add a new operator over a method. Ruby is object oriented, meaning you are calling methods on objects.

[+] jmcdonald-ut|10 years ago|reply
He addresses this in his post.

  if x.in? my_set   # very ugly
With that said, I personally don't agree with the post.
[+] fleitz|10 years ago|reply
Then why have 2 * 4 when you can write 2.multiply_by 4...

What I love about ruby is its focus on making programming delightful rather than adhering to weird ass rules like 'Ruby is object oriented, meaning you are calling methods on objects.' that people pretend are laws of physics when really you can break them anytime you want, unlike laws of physics.

Similar to the way you can write

  def foo
    "bar"
  end 
instead of

  class Kernel
  
    def foo
      "bar"
    end
  
  end
[+] nvader|10 years ago|reply
I actually found it more interesting that Ruby hashmaps ("hashes" :S) preserve insertion order and guarantee predictable insertion.

I was taught to never trust the ordering returned by iterating over keys of hashmaps because it can be a source of bugs as you move between architectures or interpreters. If you need a guaranteed ordering, keep (and pay for) the appropriate auxiliary data structure.

Has this lesson become obsolete? Perhaps "computers are fast" so now Ruby can afford to use ordered hashmaps everywhere. On the other hand, I know Go chose to randomize iteration order of keys on purpose so developers cannot rely on them.

[+] bradhe|10 years ago|reply
It's a side effect of their implementation and you should continue to not trust their default ordering.
[+] guptaneil|10 years ago|reply
When I was first learning Ruby, having to invert my natural thought process in order to use `include?` was one of the most frustrating things I had to get used to. I think that's more a testament to how amazing Ruby is at imitating natural language patterns when that was my biggest complaint.

Having said that, I don't agree that it needs to be an operator over a method. I agree that it would be prettier, but methods provide additional benefits like being easy to override or pass as arguments to other methods (like :respond_to?). If you're ok with a method, you can easily monkey patch ruby to support an `in` (or `in?`) method yourself.

[+] Skoofoo|10 years ago|reply
One of my favorite aspects of Ruby is that everything is an object with methods. Adding global operators/functions like this would only complicate the language.

> But we also -- perhaps more often? -- ask questions like "Is this item part of this group?" We are asking a question about the item.

Here we are actually asking the group a question about itself. An item would not know a group's contents.

[+] aetherson|10 years ago|reply
If we're talking about the natural language question, "Is Bob part of the Physics Department," then sometimes we conceptualize "groups" as more like tags. Like, Bob has a tag that says, "->physics-dept." And so we ask Bob if he has that tag. He doesn't need to know the entire list of people who also have that tag in order to answer that question authoritatively.
[+] omaranto|10 years ago|reply
> One of my favorite aspects of Ruby is that everything is an object with methods. Adding global operators/functions like this would only complicate the language.

But people love operators, that's why Ruby already includes loads of them instead of giving them identifier names and requiring you to call them with a dot. You have x+y instead of x.plus y, x==y instead of x.equals? y, x<y instead of x.less_than? y, most people write x..y instead of Range.new(x,y), etc. I don't think most Ruby programmers or the language designers agree with you about not wanting operators.

[+] golfadas|10 years ago|reply
Totally agree with you. I do think it is more natural to ask a collection if it has an element. On the other hand, it would be possible for Object to have an in? method that would receive a collection.
[+] Benjamin_Dobell|10 years ago|reply
> if item not in collection # travesty!

> if ! (item in collection) # ok

Riiiiiiiight. No more language suggestions from you, thanks ;)

[+] LouisSayers|10 years ago|reply
Agreed

> if item not in collection

reads quite nicely. I don't see what the problem is there? Anyway, I don't think his one gripe with this is enough reason to throw the rest of his argument out.

[+] unknown|10 years ago|reply

[deleted]

[+] singularity2001|10 years ago|reply
>> if item not in collection

he should have suggested

if not item in collection

which should then work out of the box anyways

[I completely agree with the need for the 'in' operator]

[+] luiz-pv9|10 years ago|reply

  if x.in? my_set   # very ugly
I guess we disagree there. This is arguably more readable than most languages with `in?` being still just a method.
[+] kelseydh|10 years ago|reply
I agree, I quite like it as a method as it keeps its congruence with .include? as an opposite of .in? (what .in? does should have been what .include? did from the get go).

Perhaps another way of doing this is calling the method .within?

[+] woodruffw|10 years ago|reply
This would go against the ruby style of using predicates for this sort of thing (think `include?`, `empty?`, `nil?`).

I personally wouldn't be in favor of it.

Addition: Arguing that "Ruby isn't English" and then stating conformity to mathematical notation as a benefit seems hypocritical. Programming languages (besides APL, maybe) do not use strict mathematical notation, and we shouldn't want them to.

[+] efaref|10 years ago|reply
.include? isn't really a predicate, as predicates are typically unary. Rather, it's the 'member of' relational operator written in the wrong direction. Since we don't have '∈' in ascii, the author is proposing using the word 'in' instead.

I do disagree with the author on one point: 'not in' should also be a valid operator, representing '∉'.

But I don't use Ruby; I mostly use Python, which has these operators.

[+] LouisSayers|10 years ago|reply
I don't think it 'goes against' anything... it's simply a more concise way of doing the .include? - it's syntactic sugar.

And as he points out, 'in' is already a keyword anyway - so if it makes a more readable way of doing things, then why not?

[+] Phemist|10 years ago|reply
As for programming languages, I've always wondered how languages would've looked if computers, and as a result programming languages, had been invented in non-english speaking countries.

An immediate example that comes to mind is Python's use of None, rather than null (like in Java/JavaScript). I remember speaking in Dutch about Java in college was always slightly awkward, because it was easy to confuse "null" with 0 (or "nul"). I wonder if Guido (being Dutch) called the Python void type "None" on purpose, to avoid awkwardness when speaking about it in Dutch.

[+] strong_code|10 years ago|reply
I understand the perceived benefit of compositional eloquence that this may add (pretty much borrowing from Python) but as others have pointed out, this is incongruent to the design of Ruby as a language and how it treats the relation between objects and their methods. Additionally, you lose any compositional elegance you may have gained when you decided not to use:

  x not in y
and instead propose:

  !(x in y)
Seems like a zero-sum addition to the language to me.
[+] qewrffewqwfqew|10 years ago|reply
I find `not in` highly dubious - it makes the expression grammar awkward and harder to parse. Is `not in` a two-token operator? Or is `not` an adverb in this context? What else resembles this?

To cite an alternatice, in Tcl, `in` is an operator and its negation is `ni`. A cute pun and echo of Monty Python that I'm disappointed Python didn't follow :).

[+] VeejayRampay|10 years ago|reply
Could be worse, consider testing for inclusion in Javascript with Array#indexOf, where you don't even get a boolean value back.

The fact that the Ruby method is called include? and not includes? is annoying though.

[+] unknown|10 years ago|reply

[deleted]

[+] u320|10 years ago|reply
"in" is already a reserved word in Ruby.
[+] dorianm|10 years ago|reply
/me Comes to this thread, upvotes all the comment mentionning `.in?`
[+] newobj|10 years ago|reply
so.. is 10 'in' 10..100? is 100?
[+] VeejayRampay|10 years ago|reply
10..100 is a Range in Ruby. 10..100 does include 100 (it includes both bounds). On the other hand 10...100 (note the three dots) does not.
[+] tom-lord|10 years ago|reply

    [1] pry(main)> 10..100
    => 10..100
    [2] pry(main)> (10..100).class
    => Range
    [3] pry(main)> (10..100).to_a
    => [10, 11, 12, 13, 14, ..., 99, 100]