Replying to myself again...

If writing "loose" <=> methods really isn't okay, then it sure would be 
nice to have a fast sgn (or sign) method built-in to Numeric.  Then I 
could write a "string" <=> method of the form (y - x).sgn

I know that I can use "<=> 0" to compute the sign of a number, but 
Numeric has a native abs method, so it should have a native sgn method. 
  In my opinion, abs without sgn is like quo without modulo or sin 
without asin.

This was discussed recently (but didn't go anywhere) on ruby-talk: 
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/235566

   David

David Flanagan wrote:
> I agree that the current documentation and implementation are not 
> inconsistent.  Implicit in my question was a concern about efficiency. I 
> have been assuming that being allowed to write <=> methods that return   
> any number less than zero or any number greater than zero is more 
> efficient than having to include the extra code to "clamp" those values 
> to -1 and +1.
> 
> A simple benchmark is included.  It shows that it is about 25% faster to 
> write a "loose" <=> method than a "strict" <=> method. (But only if the 
> loose <=> method returns an Integer.  If it returns a Float, then the 
> loose method is actually slower.)
> 
> Anyway, it is this efficiency issue that is at the root of my question.
> Given that Ruby's documentation is not always really detailed, I 
> wondered if the docs are really definitive here.  If it is actually 
> legal to write a loose <=> method, it would be nice to know that!
> 
>     David
> 
> Benchmark code follows:
> class Slow
>   def initialize(x)
>     @x = x
>   end
> 
>   def value
>     @x
>   end
> 
>   def <=>(other)
>     y = other.value
>     if @x < y
>       -1
>     elsif @x > y
>       1
>     else
>       0
>     end
>   end
> end
> 
> class Fast
>   def initialize(x)
>     @x = x
>   end
> 
>   def value
>     @x
>   end
> 
>   def <=>(other)
>     other.value - @x
>   end
> end
> 
> f = []
> s = []
> 
> 100000.times do
>   x = rand(100000)
>   f << Fast.new(x)
>   s << Slow.new(x)
> end
> 
> require 'benchmark'
> include Benchmark
> 
> bmbm(2) do |x|
>   x.report("Fast") { f.sort }
>   x.report("Slow") { s.sort }
> end
> 
> 
> ------------------------------------------------
> Here are the benchmark results on my aging Linux system:
> 
> Rehearsal ----------------------------------------
> Fast   4.390000   0.000000   4.390000 (  4.403584)
> Slow   5.640000   0.020000   5.660000 (  5.657363)
> ------------------------------ total: 10.050000sec
> 
>            user     system      total        real
> Fast   4.020000   0.000000   4.020000 (  4.025188)
> Slow   5.500000   0.000000   5.500000 (  5.503963)
> 
> 
> 
> Marte Raphael Y. Soliza wrote:
>> I think there's nothing wrong with the implementation and 
>> documentation. True, an erronous implementation of <=> will still work 
>> if this is the implementation, but if we use exact comparisons such as 
>> == -1, trichotomy might be broken. For example, if two comparable 
>> objects of the same class, say a and b, are compared, and a is neither 
>> less than, equal, nor greater than b, then what is the relationship of 
>> a to b? This will give us a hint that the implementation of <=> is 
>> incorrect, and that's good, but I believe it's better (and safer) to 
>> have a fallback. If we throw an error that results from <=> returning 
>> a value other than -1, 0, and 1, then it might have an impact to 
>> efficiency especially in sorting huge array of values because we added 
>> an overhead of checking if the value returned is correct.
>>
>> On 4/1/07, *David Flanagan* <david / davidflanagan.com 
>> <mailto:david / davidflanagan.com>> wrote:
>>
>>     Replying to my own post...
>>
>>     Let me add that the existing numeric <=> operators all do appear to
>>     strictly return -1, 0, or +1.  That is, they don't simply return 
>> y-x to
>>     compute a value less than, equal to, or greater than zero.  This 
>> would
>>     argue that the current documentation of Comparable is correct, but 
>> that
>>     the implementation is written so that it works even for broken <=>
>>     operators.
>>
>>     Anyway, I should say that it was probably presumptuous of me to 
>> assume
>>     that the documentation is incorrect.  Everything I've seen in writing
>>     says that <=> must return -1,0, or +1.  The implementation in 
>> compar.c
>>     makes it appear that this is not the case, however. I was not able to
>>     find any discussion of the return value of <=> in the ruby-talk
>>     archives...
>>
>>
>>
>> -- 
>> "Life is unfair... but beautiful."
>> Scarlette Krimson
> 
>