
An 'in' operator for Ruby - charlieegan3
http://rubyhacker.com/blog2/20151202.html
======
tyre
Rails implements this as `in?`

[https://github.com/rails/rails/blob/d61baee52adcd1baebe15f10...](https://github.com/rails/rails/blob/d61baee52adcd1baebe15f1065a0805857571f19/activesupport/lib/active_support/core_ext/object/inclusion.rb#L10)

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.

~~~
fleitz
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

~~~
wycats
The difference here is that ` _` literally maps onto a method called `_ ` in
Ruby. I find this aspect of Ruby delightful and it's not something I willingly
chip away at.

Generally speaking, Ruby eschews syntax that invokes a protocol behind the
scenes for a consistent 1:1 mapping between method syntax and the methods they
invoke.

------
nvader
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
It's a side effect of their implementation and you should continue to not
trust their default ordering.

~~~
nvader
It appears that since Ruby 1.9 they guarantee insertion order: [http://ruby-
doc.org/core-2.3.0/Hash.html](http://ruby-doc.org/core-2.3.0/Hash.html)

I guess there are two approaches to solving the problem of people using your
data structures the wrong way.

Edit: wrong link

~~~
ghayes
As opposed to Go [0]

> When iterating over a map with a range loop, the iteration order is not
> specified and is not guaranteed to be the same from one iteration to the
> next. Since Go 1 the runtime randomizes map iteration order, as programmers
> relied on the stable iteration order of the previous implementation.

[0] [https://blog.golang.org/go-maps-in-action](https://blog.golang.org/go-
maps-in-action)

------
guptaneil
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
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
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.

------
Benjamin_Dobell
> if item not in collection # travesty!

> if ! (item in collection) # ok

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

~~~
LouisSayers
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.

~~~
theodorton
unless item in collection

Obviously is the best choice

~~~
pmontra
Yes, and it's the idiomatic Ruby one.

------
luiz-pv9

      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
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?

~~~
tragomaskhalos
Seconded. One of the ways in which I prefer Ruby to Python is the way that it
always favours "plain methods" over "syntax that maps to special methods under
the covers".

~~~
omaranto
But that's not true, as far as I can tell. Ruby does allow you to write
5.+(8), but as far as I can tell most people prefer 5+8. Ruby also has special
syntax for <, == and indexing arrays. What things does Python have special
syntax for that Ruby doesn't? Off the top of my head I can only remember "in".

------
woodruffw
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
.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.

~~~
bhaak
It's not a problem using non ASCII method names in Ruby:
[https://gist.github.com/bhaak/91428b9aee88ac50dd1d](https://gist.github.com/bhaak/91428b9aee88ac50dd1d)

I can't think of any modern programming language that isn't unicode aware even
though for the standard library methods, there are very good reasons not to
use them (I know, Perl 6 does but even in this case there are ASCII
fallbacks).

You should also have very good reasons to put methods on the root class of
your class hierarchy.

~~~
vidarh
> It's not a problem using non ASCII method names in Ruby

Making it easy for people to type them, on the other hand...

~~~
bhaak
> Making it easy for people to type them, on the other hand...

That's a problem of the code editors people are using. ;-)

I'm often surprised with how dysfunctional editors people are programming.

For example if all editors would show tabs and spaces (or whitespace in
general) in a reasonable way, we wouldn't have had that much pointless
discussion about the correct indentation whitespace character.

------
Phemist
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
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
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
:).

~~~
Someone
You should be happy, as Python 3 would have renamed it to _" Ekke Ekke Ekke
Ekke Ptang Zoo Boing!"_

As to the "what else resembles this"? I would turn it around and ask what else
could resemble this. I'm not sure the conclusion would be that "not in" is a
good thing, but not sure of the reverse, either:

    
    
      if x not = 3
    

looks weird, but I think I could grow to like it.

~~~
efaref
Well, shell has the '-ne' operator, which is 'not equals' in a terser style.

Really '!=' is just an attempt at rendering '≠' using only ASCII characters.
They're a bit like digraphs and trigraphs in C/C++, except everyone is used to
them.

I wonder if Unicode is ubiquitous enough now that you could write a language
where the real maths operators were used instead. What would that look like?

~~~
yorwba
Haskell allows unicode in operators and there appear to be packages that
implement aliases for the default ASCII versions.

[https://wiki.haskell.org/Unicode-symbols](https://wiki.haskell.org/Unicode-
symbols)

------
AaronLasseigne
If it's this importing why not propose it: [https://bugs.ruby-
lang.org/](https://bugs.ruby-lang.org/)

Ruby has a place for this sort of thing and they'll answer you.

~~~
gkop
It was proposed in 2010 and rejected by Matz in 2012: [https://bugs.ruby-
lang.org/issues/3845](https://bugs.ruby-lang.org/issues/3845)

~~~
singularity2001
something went wrong between

Matz: I am neutral for this proposal.

... ...

Matz: This proposal is only for cosmetics. I don't want a new operator that
does not introduce something new.

[I personally disagree and think the 'in' operator should be added]

------
VeejayRampay
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.

------
ishtu
>Ruby isn't English

because it's Japanese [https://www.new-bamboo.co.uk/blog/2010/12/17/learning-
japane...](https://www.new-bamboo.co.uk/blog/2010/12/17/learning-japanese-the-
rubyist-way/)

------
singularity2001
One day we will have a 'no-awkward'™ english like syntax:
[https://github.com/pannous/english-
script](https://github.com/pannous/english-script)

~~~
pavlov
AppleScript tried to do just that:

[https://en.wikipedia.org/wiki/AppleScript](https://en.wikipedia.org/wiki/AppleScript)

It doesn't work out very well in practice. Inevitably the syntax diverges, and
then it's pretty confusing for the novice user: why do some sentences work but
most don't?

~~~
singularity2001
from my experience Apple's problem with AppleScript was not so much diverging
syntax but constant undebuggable crashes

------
sargegood
Yes! Do it.

------
dorianm
/me Comes to this thread, upvotes all the comment mentionning `.in?`

------
newobj
so.. is 10 'in' 10..100? is 100?

~~~
VeejayRampay
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.

~~~
jschulenklopper
> On the other hand 10...100 (note the three dots) does not. reply > On the
> other hand 10...100 (note the three dots) does not.

To be clear, 10...100 includes 10, but not 100. So, it includes one bound: the
one mentioned first, the lower bound.

    
    
      (10...100).to_a
      => [10, 11, 12, 13, ... 98, 99]

