Commit 902b2ce3 authored by KOBAYASHI Shuji's avatar KOBAYASHI Shuji

Fix `Rational#==(Complex)`

Consider a Numreic class like `Complex` that does not have `<=>` but `==`
works (`0i == 0r` is `true`).
parent 8ad777c7
......@@ -62,6 +62,19 @@ class Rational < Numeric
nil
end
end
def ==(rhs)
if rhs.is_a?(Integral)
return numerator == rhs if denominator == 1
rhs = Rational(rhs)
end
if rhs.is_a?(Rational)
numerator * rhs.denominator == denominator * rhs.numerator
else
rhs == self
end
end
end
class Numeric
......
class UserDefinedNumeric < Numeric
def initialize(n)
@n = n
end
def <=>(rhs)
return nil unless rhs.respond_to?(:to_i)
rhs = rhs.to_i
rhs < 0 ? nil : @n <=> rhs
end
def inspect
"#{self.class}(#{@n})"
end
end
class ComplexLikeNumeric < UserDefinedNumeric
def ==(rhs)
@n == 0 && rhs == 0
end
undef <=>
end
def assert_rational(exp, real)
assert_float exp.numerator, real.numerator
assert_float exp.denominator, real.denominator
......@@ -17,7 +41,7 @@ def assert_cmp(exp, o1, o2)
if exp == (o1 <=> o2)
pass
else
flunk "", " Expected #{o1.inspect} <=> #{o2.inspect} to be #{exp}"
flunk "", " Expected #{o1.inspect} <=> #{o2.inspect} to be #{exp}."
end
end
......@@ -106,6 +130,13 @@ assert 'Rational#==, Rational#!=' do
assert_equal_rational(false, Rational(2,1), 1r)
assert_equal_rational(false, Rational(1), nil)
assert_equal_rational(false, Rational(1), '')
assert_equal_rational(true, 0r, UserDefinedNumeric.new(0))
assert_equal_rational(true, 1r, UserDefinedNumeric.new(1))
assert_equal_rational(false, 1r, UserDefinedNumeric.new(2))
assert_equal_rational(false, -1r, UserDefinedNumeric.new(-1))
assert_equal_rational(true, 0r, ComplexLikeNumeric.new(0))
assert_equal_rational(false, 1r, ComplexLikeNumeric.new(1))
assert_equal_rational(false, 1r, ComplexLikeNumeric.new(2))
end
assert 'Fixnum#==(Rational), Fixnum#!=(Rational)' do
......@@ -123,21 +154,6 @@ assert 'Float#==(Rational), Float#!=(Rational)' do
end
assert 'Rational#<=>' do
num = Class.new(Numeric) do
def initialize(n)
@n = n
end
def <=>(rhs)
rhs = rhs.to_i
rhs < 0 ? nil : @n <=> rhs
end
def inspect
"num(#{@n})"
end
end
assert_cmp(-1, Rational(-1), Rational(0))
assert_cmp(0, Rational(0), Rational(0))
assert_cmp(1, Rational(1), Rational(0))
......@@ -158,10 +174,12 @@ assert 'Rational#<=>' do
assert_cmp(-1, Rational(1,2), Rational(2,3))
assert_cmp(-1, Rational(1,2), Rational(2,3))
assert_cmp(nil, 3r, "3")
assert_cmp(1, 3r, num.new(2))
assert_cmp(0, 3r, num.new(3))
assert_cmp(-1, 3r, num.new(4))
assert_cmp(nil, Rational(-3), num.new(5))
assert_cmp(1, 3r, UserDefinedNumeric.new(2))
assert_cmp(0, 3r, UserDefinedNumeric.new(3))
assert_cmp(-1, 3r, UserDefinedNumeric.new(4))
assert_cmp(nil, Rational(-3), UserDefinedNumeric.new(5))
assert_raise(NoMethodError) { 0r <=> ComplexLikeNumeric.new(0) }
assert_raise(NoMethodError) { 1r <=> ComplexLikeNumeric.new(2) }
end
assert 'Fixnum#<=>(Rational)' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment