Skip to content

Instantly share code, notes, and snippets.

@heftig
Forked from terotil/chained_comparisons.rb
Created April 30, 2010 02:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heftig/384651 to your computer and use it in GitHub Desktop.
Save heftig/384651 to your computer and use it in GitHub Desktop.
# Always wanted to chain comparisons the snaky way?
#
# puts 'Right there!' if 5 < x <= 15
#
# There you go.
class FalseClass
['<', '>', '<=', '>='].each do |op|
eval "def #{op}(other) false end"
end
end
module ChainedComparisons
def self.included(klass)
[['<', '', -1],
['>', '', 1],
['<=', '!', 1],
['>=', '!', -1]].each do |op, neg, cmp|
klass.class_eval <<-EOS
def #{op}(other)
#{neg}(self<=>other).equal?(#{cmp}) ? other : false
end
EOS
end
end
end
[Comparable, Fixnum, Float].each do |chainable|
chainable.send :include, ChainedComparisons
end
require 'test/unit'
class TC_ChainedComparisons < Test::Unit::TestCase
def test_pairs
assert 1<2
assert !(2<2)
assert 3>2
assert !(1>2)
assert 1<=2
assert 2<=2
assert !(3<=2)
assert 3>=2
assert 2>=2
assert !(1>=2)
end
def test_chains
# < only
assert 1<2<3
assert 1<2<3<4
assert !(1<2<2)
assert !(3<2<3<4)
# > only
assert 3>2>1
assert 4>3>2>1
assert !(3>2>2)
assert !(2>3>2>1)
# mixed
assert 1<=2>=1
assert 2<=2>=2
assert 1<2<=2>=2>1
assert !(2<=2<2)
assert !(2>2<2)
assert !(1>=2>=1<0>1)
end
def test_coercion
assert 1.0<2<30000000000000000000000000000000
assert !(1.0>2<30000000000000000000000000000000)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment