This seems a ridiculously simple question to be asking, but what's the shortest/most idiomatic way of rewriting this in Ruby?
if variable == :a or variable == :b or variable == :c or variable == :d # etc.
I saw this solution:
if [:a, :b, :c, :d].include? variable
but this isn't always functionally equivalent - I believe Array#include? actually looks to see if the variable object is contained in the list; it doesn't take into account that the object may implement its own equality test with def ==(other).
As observed by helpful commentators below, that explanation isn't correct. include? does use == but it uses the == method of the items in the array. In my example, it's the symbols, rather than the == method of the variable. That explains why it's not equivalent to my first code example.
(Take, for example, Rails' Mime::Type implementation: request.format == :html may return true, but [:html].include?(request.format) will return false, as request.format is an instance of Mime::Type, not a symbol.)
The best I have so far is:
if [:a, :b, :c, :d].select {|f| variable == f}.any?
but it seems somewhat cumbersome to me. Does anyone have better suggestions?
Actually, #include? does use ==. The problem arises from the fact that if you do
[:a].include? foo
it checks :a == foo, not foo == :a. That is, it uses the == method defined on the objects in the Array, not the variable. Therefore you can use it so long as you make sure the objects in the array have a proper == method.
In cases where that won't work, you can simplify your statement by removing the select statement and passing the block directly to any:
if [:a, :b, :c, :d].any? {|f| variable == f}
It looks like Array#include? does use ==:
>> class AString < String
>> def ==(other)
>> self[0] == other[0]
>> end
>> end
>> asdf = AString.new "asdfg"
=> "asdfg"
>> b = AString.new 'aer'
=> "aer"
>> asdf == b
=> true
>> [asdf].include? b
=> true
The Array#include? documentation also explains this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With