In ruby you can check ranges via de ‘range’ language construct. For example: (12..23).include?( value).
But how about chaining ‘<', '<=', '=>‘ and ‘>’ operators.
For example. currently in Ruby I must write the following
if 10 < x && x < 15 # code end
Why isn’t it possible to write
if 10 < x < 15 # code end
Well in fact it is possible with some hacks :)
The example below is only valid for Fixnum, but it describes the possibilities:
The hack is to just simply return the right hand. In Ruby this shouldn’t be a problem, because every object/values is true except false and nil.
class Fixnum
def <(val)
super ? val : false
end
def <=(val)
super ? val : false
end
def >(val)
super ? val : false
end
def >=(val)
super ? val : false
end
end
To make this work the FalseClass should also support these operators, and simply return false to make the complete expression return false if one of them fails:
class FalseClass
def <(val)
false
end
alias :<= :<
alias :> :<
alias :>= :<
end
So 10 < x just returns 'x' on succes and returns false on error.
if 10 < x < 15 # code end
I'm wondering what could/would be the 'problem' by using this construct? Is there a specific reason this has not been implemented this way?
BTW: just found a 'nice' implementation for this construct on: http://refactormycode.com/codes/1284-chained-comparisons-in-ruby
[:<, :>, :<=, :>=].each do |operator|
[Float, Fixnum, Comparable].each do |klass|
klass.class_eval {
alias_method("__#{operator}__", operator)
define_method(operator) do |operand|
send("__#{operator}__", operand) and operand
end
}
end
FalseClass.send(:define_method, operator) { false }
end