rbs icon indicating copy to clipboard operation
rbs copied to clipboard

[Comparable] Add in Comparable::_CompareToZero

Open sampersand opened this issue 1 month ago • 4 comments

This PR adds in the Comparable::_CompareToZero interface, which is the actual return type that Comparable expects <=> to return.

sampersand avatar Nov 04 '25 05:11 sampersand

I believe it should return Integer? because the document says,

returning a value less than 0, returning 0, or returning a value greater than 0

https://docs.ruby-lang.org/en/master/Comparable.html

Also, I cannot think of any specific problems that this change would solve. Could you give me an example?

ksss avatar Nov 05 '25 02:11 ksss

Yeah, the docs are correct—it actually checks the return valeu for ret < 0 and ret > 0.

While all of the stdlib returns an Integer (-1, 0, or 1), I believe Comparable was designed this way to let people do things like returning the diff between two Floats. For example:

class Kilometers
  include Comparable
  
  def initialize(value) = @value = value.to_f
  def to_f = @value
  def <=>(other) = @value - other.to_f
  # ...
end

p Kilometers.new(1.2) < Kilometers.new(3.4)

This doesn't typecheck under the current RBS signatures, but does work in Ruby

sampersand avatar Nov 11 '25 01:11 sampersand

  def <=>(other) = @value - other.to_f
  def <=>(other) = @value <=> other.to_f

The point is still valid: MyNumber would be a better example.

ParadoxV5 avatar Nov 11 '25 02:11 ParadoxV5

@ParadoxV5 this is actually the way that ruby 0.49 did it:

% ./fixed/ruby <<RUBY
class X
   include Comparable
   def <=>(r) "A" <=> r end
end

print(X.new() <=> "Q")
RUBY
-16

sampersand avatar Nov 12 '25 06:11 sampersand