Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Update the code, README and specs to be slightly less obviously ridic…

…ulous. I still probably wouldn't use this in practice, but now it's plausible.
  • Loading branch information...
commit f6fc068749148f89b08ac7c3f5b8efa5e1784182 1 parent 5358503
@wycats authored
View
31 README.markdown
@@ -15,4 +15,33 @@ This provides a module which you can mix into any class to get chainable compare
puts pick_line("Yehuda")
puts pick_line("Evan")
-This works by overriding the <, >, <=, and >= operators on the class in question, as well as in FalseClass. I probably wouldn't override built-in classes this way without thinking pretty hard about the consequences.
+This works by overriding the <code><</code>, <code>></code>, <code><=</code>, and <code>>=</code> operators on the class in question, as well as in <code>FalseClass</code>. I probably wouldn't override built-in classes this way without thinking pretty hard about the consequences.
+
+This works if you don't need to define your own comparison methods (i.e. your class inherits from a superclass that defines them). Otherwise, you can define <code><=></code> as usual:
+
+ class Version
+ include ChainablyComparable
+
+ attr_accessor :version
+
+ def initialize(version)
+ @version = version.split(".").map {|segment| segment.to_i }
+ end
+
+ def <=>(other)
+ a, b = normalize(@version, other.version)
+ a <=> b
+ end
+
+ private
+ def normalize(a, b)
+ if a.size > b.size
+ [a.dup, b.dup.fill(0, a.size - 1, a.size - b.size)]
+ else
+ [a.dup.fill(0, b.size - 1, b.size - a.size), b.dup]
+ end
+ end
+ end
+
+ version = Version.new("2.0")
+ Version.new("1.0.0") < version < Version.new("3")
View
40 lib/chainable_compare.rb
@@ -17,17 +17,35 @@ def #{operator}(other)
end
module ChainablyComparable
- def self.included(klass)
- %w(< > <= >=).each do |operator|
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def #{operator}(other)
- if super
- ChainableCompare.new(other)
- else
- false
- end
- end
- RUBY
+ def <(other)
+ if (self <=> other) == -1
+ ChainableCompare.new(other)
+ else
+ false
+ end
+ end
+
+ def >(other)
+ if (self <=> other) == 1
+ ChainableCompare.new(other)
+ else
+ false
+ end
+ end
+
+ def <=(other)
+ if (self <=> other) <= 0
+ ChainableCompare.new(other)
+ else
+ false
+ end
+ end
+
+ def >=(other)
+ if (self <=> other) >= 0
+ ChainableCompare.new(other)
+ else
+ false
end
end
View
36 spec/chainable_compare_spec.rb
@@ -1,32 +1,46 @@
require "spec_helper"
-class Fixnum
+class ComparableInteger
include ChainablyComparable
+
+ attr_accessor :number
+
+ def initialize(number)
+ @number = number
+ end
+
+ def <=>(other)
+ @number <=> other.number
+ end
end
describe "chainable compare" do
+ def int(integer)
+ ComparableInteger.new(integer)
+ end
+
it "works for 1 < x < 5 when x is 3" do
- x = 3
- (1 < x < 5).should be_true
+ x = int(3)
+ (int(1) < x < int(5)).should be_true
end
it "works for 1 < x < 5 when x is 0" do
- x = 0
- (1 < x < 5).should be_false
+ x = int(0)
+ (int(1) < x < int(5)).should be_false
end
it "works for 1 < x < 5 when x is 6" do
- x = 6
- (1 < x < 5).should be_false
+ x = int(6)
+ (int(1) < x < int(5)).should be_false
end
it "works for 10 > x <= 9 where x = 7" do
- x = 7
- (10 > x <= 9).should be_true
+ x = int(7)
+ (int(10) > x <= int(9)).should be_true
end
it "works for 10 > x <= 9 where x = 10" do
- x = 10
- (10 > x <= 9).should be_false
+ x = int(10)
+ (int(10) > x <= int(9)).should be_false
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.