tags:

views:

185

answers:

6

I want to test whether a equals 1 or 2

I could do

a == 1 || a == 2

but this requires repeating a (which would be annoying for longer variables)

I'd like to do something like a == (1 || 2), but obviously this won't work

I could do [1, 2].include?(a), which is not bad, but strikes me as a bit harder to read

Just wondering how do to this with idiomatic ruby

+9  A: 

Your first method is idiomatic Ruby. Unfortunately Ruby doesn't have an equivalent of Python's a in [1,2], which I think would be nicer. Your [1,2].include? a is the nearest alternative, and I think it's a little backwards from the most natural way.

Of course, if you use this a lot, you could do this:

class Object
  def member_of? container
    container.include? self
  end
end

and then you can do a.member_of? [1, 2].

Peter
Why not to rename `member_of?` to `in?`?
ib
@ib: whatever name you like; `in` sounds good as well.
Peter
+4  A: 

First put this somewhere:

class Either < Array
  def ==(other)
    self.include? other
  end
end

def either(*these)
  Either[*these]
end

Then, then:

if (either 1, 2) == a
  puts "(i'm just having fun)"
end
yjerem
This is remarkably similar to the syntax for Perl 6's `any` and `all` junctions. Is there an easy way to allow `a == (either 1, 2)` as well?
Chris Lutz
@Chris Lutz: Not in the general case. As you can see from the method implementation, the `==` operator is just semantic sugar for calling the `==` method of the object on its left-hand side.
Chuck
+4  A: 

I don't know in what context you're using this in, but if it fits into a switch statement you can do:

a = 1
case a
when 1, 2
  puts a
end

Some other benefits is that when uses the case equality === operator, so if you want, you can override that method for different behavior. Another, is that you can also use ranges with it too if that meets your use case:

when 1..5, 7, 10
Jack Chu
+3  A: 
a.to_s()=~/^(1|2)$/
ghostdog74
so, gross, but valid
Pestilence
gross or not, its up to individual. To me, going the extra mile of creating custom classes, doing fancy things, is gross.
ghostdog74
Setting up a regex-evaluating finite state machine and converting a number into a string just to test equality is far more extravagant and "fancy" than Jeremy's `either` method.
Chuck
to each his own. It takes just 1 line to test the numbers and I am super fine with that!
ghostdog74
+1  A: 

Maybe I'm being thick here, but it seems to me that:

(1..2) === a

...works.

Shadowfirebird
They're not equivalent. Yours is true if a = 1.5 (for example), but the original if is not.
Brian Young
Good point, thank you.
Shadowfirebird
Thank you -- I hadn't seen that. You learn a new thing every day...
Shadowfirebird
+1  A: 

Another way would be to petition "Matz" to add this functionality to the Ruby specification.

if input == ("quit","exit","close","cancel") then
  #quit the program
end

In fact, the case-when statement lets you do exactly that:

case input when "quit","exit","close","cancel" then 
  #quit the program
end

When written on one line like that, it acts and almost looks like an if statement. Is the bottom example a good temporary substitution for the top example? You be the judge.

Arcolye
Personally I don't like the idea of using `if input == ("quit", "exit"...)` as it messes badly with testing for array equality. The use of `case ... when ...` is nicer because it is valid syntax, though it's a bit unexpected. I think the use of an "in" operator to test for inclusion in an array, as mentioned in other responses, would be a good addition to the language.
Greg