I’d like to implement a class in Ruby that’s comparable (using the <=> operator) with any Fixnum, and vice-versa. This will ultimately be used in a range. Here is an outline of my class:
class N
include Comparable
attr :offset
def initialize(offset = 0)
@offset = offset
end
def succ
N.new(@offset + 1)
end
def +(offset)
N.new(@offset + offset)
end
def <=>(other)
return @offset <=> other.offset if other.kind_of? N
return 1 # N is greater than everything else
end
end
def n; N.new(0); end
Now this works great when used in n..n+2 and n..999, but not in 1..n. This is due to the fact that n <=> 1 works but 1 <=> n does not (returns nil).
Is there any way I can get Fixnum to treat my N class as a comparable object? Your thoughts are appreciated 🙂
If you want to implement your own number type, you must implement
coerce:All of Ruby’s builtin number types in the core library, all number types in the standard library, as well as all third-party number types use the
coerceprotocol to find a common type in order to make operators such as+,*and==commutative and-,/and<=>symmetric.It’s not quite clear to me what the semantics of
Nshould be, so the above implementation is only an example.