Project

General

Profile

Bug #7342

String#<=> checks for a #to_str method on other but never uses it?

Added by jballanc (Joshua Ballanco) over 7 years ago. Updated over 7 years ago.

Status:
Closed
Priority:
Normal
Target version:
ruby -v:
2.0.0
Backport:
[ruby-core:49279]

Description

=begin
This isn't exactly a bug, as much as a request for clarification. I was looking at the semantics of the (({<=>})) operator and noticed something curious. For most classes, when evaluating (({thing <=> other})), if (({other})) is not of a compatible type, then (({nil})) is returned.

The exceptions (as far as I can find) are String and Time. For the Time class, if (({other})) is not a kind of (({Time})), then the reverse comparison (({other <=> thing})) is tried and the inverse of this result is returned (if not nil). For String, the reverse comparison is only tried IF (({other.respond_to?(:to_str)})), HOWEVER the referenced (({other.to_str})) method is never called. For example:

class NotAString
  def <=>(other)
    1
  end
  def to_str
    raise "I'm not a string!"
  end
end

"test" <=> NotAString.new #=> -1

This seems very counterintuitive to me. I would expect that if my class implemented (({to_str})), that the return value of this would be used for comparison.
=end


Files

string_cmp.diff (1.9 KB) string_cmp.diff jballanc (Joshua Ballanco), 11/21/2012 07:54 PM

Also available in: Atom PDF