Actions
Bug #18937
closedInconsistent definitions of Complex#<=> and Numeric#<=> with others
Description
Object#<=> says "Returns 0 if obj
and other
are the same object or obj == other
" .
https://ruby-doc.org/core-3.1.2/Object.html#method-i-3C-3D-3E
However, neither Complex#<=> nor Numeric#<=> satisfies that definition.
num1 = Complex(0, 42)
num2 = Complex(0, 42)
p num1.equal?(num2) #=> false
p num1 == num2 #=> true
# using Complex#<=>
p num1 <=> num2 #=> nil
# using Numeric#<=>
Complex.remove_method(:<=>)
p num1 <=> num2 #=> nil
# using Object#<=> (Kernel#<=>)
Numeric.remove_method(:<=>)
p num1 <=> num2 #=> 0
Complex#<=> has another problem that it does not coerce numeric objects while Integer#<=> and Float#<=> do.
This prevents users from adding yet another complex class having #<=>.
Here is my proposal of Complex#<=> behavior (in Ruby).
This considers #15857, complex numbers are comparable when their imaginary parts are 0.
class Complex
def <=>(other)
return (self == other ? 0 : nil) if self.imag != 0
if other.kind_of?(Complex)
if other.imag == 0
return self.real <=> other.real
else
return nil
end
elsif other.kind_of?(Numeric) && other.real?
return self.real <=> other
elsif other.respond_to?(:coerce)
num1, num2 = other.coerce(self)
return num1 <=> num2
else
return nil
end
end
end
Actions
Like0
Like0Like0Like0Like0Like0Like0