Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Numeric <=>

6 views
Skip to first unread message

ChrisH

unread,
Nov 8, 2005, 3:47:58 PM11/8/05
to
Just looking at the docs on ruby-doc.org and noticed that Numeric
implements <=> so it returns 0 or nil. It also includes Comparable,
which depends on <=> returning -1, 0 or 1. Any one know why
Numeric doesn't provide all three expected values?

Cheers
Chris

Eric Hodel

unread,
Nov 8, 2005, 4:04:12 PM11/8/05
to

Numeric is an abstract class. Fixnum, Bignum, Float, BigDecimal, etc
need to override #<=> appropriately.

--
Eric Hodel - drb...@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04


ChrisH

unread,
Nov 9, 2005, 10:09:19 AM11/9/05
to
Thanks Eric. I just wonder why Numeric doesn't implement it properly?
Is it implented this way because Comparable requires it, but since
Numeric is Abstract it doesn't need to actually work?

This is just idle curiosity, but any insight is appreciated

Cheers

Christophe Grandsire

unread,
Nov 9, 2005, 11:01:45 AM11/9/05
to
Selon ChrisH <chris...@gmail.com>:

> Thanks Eric. I just wonder why Numeric doesn't implement it properly?

Probably because it can't. I'm not completely up-to-date with the Numeric
inheritance chain, but I guess for instance Complex numbers also inherit from
Numeric. Being Numeric doesn't necessarily mean that there is a meaningful
order among the objects.

Then again, I'm out on a limb here, and may be completely wrong.
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.


Robert Klemme

unread,
Nov 9, 2005, 11:37:41 AM11/9/05
to
Christophe Grandsire wrote:
> Selon ChrisH <chris...@gmail.com>:
>
>> Thanks Eric. I just wonder why Numeric doesn't implement it
>> properly?
>
> Probably because it can't. I'm not completely up-to-date with the
> Numeric inheritance chain, but I guess for instance Complex numbers
> also inherit from Numeric. Being Numeric doesn't necessarily mean
> that there is a meaningful order among the objects.

Although I agree with your analysis that Numeric can't properly implement
<=> the question remains why <=> is actually implemented in Numeric. ATM
I cannot see what necessitates it. Including Comparable is not a reason
IMHO because that will break either way (i.e. with missing <=> and with
incomplete implemented <=>).

> Then again, I'm out on a limb here, and may be completely wrong.

Not completely but I have the feeling we're still not there. Someone
probably needs to take the time and have a look at the sources...

Kind regards

robert

Eric Hodel

unread,
Nov 9, 2005, 1:45:56 PM11/9/05
to

If you forget to define #<=> in your Numeric subclass you have a
safety net and your code won't mysteriously die.

daz

unread,
Nov 9, 2005, 2:02:23 PM11/9/05
to

Robert Klemme wrote:
> Christophe Grandsire wrote:
> > Selon ChrisH:

#-------------
class Roo < Numeric; end

a = Roo.new
b = Roo.new
c = a

p a <=> b #-> nil
p a <=> c #-> 0
#-------------

Well, that's helpful!

Ruby (like me) hasn't a clue what a 'Roo' is,
but it's able to tell that a == c which might
be enough to keep a routine running.


<Changelog>
Wed Nov 20 01:52:21 2002 Yukihiro Matsumoto <ma...@ruby-lang.org>

* numeric.c (num_cmp): added to satisfy Comparable assumption.
</>

http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/numeric.c.diff?r1=1.59;r2=1.60;f=h


daz

Robert Klemme

unread,
Nov 10, 2005, 4:32:08 AM11/10/05
to

Definitely not:

>> ar=(0..2).map { Roo.new }
=> [#<Roo:0x101957e8>, #<Roo:0x101957b8>, #<Roo:0x10195788>]
>> ar.sort
ArgumentError: comparison of Roo with Roo failed
from (irb):14:in `sort'
from (irb):14
from :0

>> Roo.new < Roo.new
ArgumentError: comparison of Roo with Roo failed
from (irb):21:in `<'
from (irb):21
from :0

This is what happens in the "standard cases".

>> class Bar;include Comparable; end
=> Bar
>> ar=(0..2).map { Bar.new }
=> [#<Bar:0x10182360>, #<Bar:0x10182330>, #<Bar:0x10182300>]
>> ar.sort
NoMethodError: undefined method `<=>' for #<Bar:0x10182360>
from (irb):20:in `sort'
from (irb):20
from :0


>> Foo = Class.new
=> Foo
>> ar=(0..2).map { Foo.new }
=> [#<Foo:0x1018bc60>, #<Foo:0x1018bbe8>, #<Foo:0x1018bbb8>]
>> ar.sort
NoMethodError: undefined method `<=>' for #<Foo:0x1018bc60>
from (irb):17:in `sort'
from (irb):17
from :0


> <Changelog>
> Wed Nov 20 01:52:21 2002 Yukihiro Matsumoto <ma...@ruby-lang.org>
>
> * numeric.c (num_cmp): added to satisfy Comparable assumption.

Hm... Doesn't sound as if the assumption was satisfied...

>
http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/numeric.c.diff?r1=1.59;r2=1.60;f=h

Kind regards

robert

daz

unread,
Nov 10, 2005, 9:19:35 AM11/10/05
to

Robert Klemme wrote:

> daz wrote:
> >
> > but it's able to tell that a == c which might
> > be enough to keep a routine running.
>
> Definitely not:
>
> >> ar=(0..2).map { Roo.new }
> => [#<Roo:0x101957e8>, #<Roo:0x101957b8>, #<Roo:0x10195788>]
> >> ar.sort
> ArgumentError: comparison of Roo with Roo failed


Those instances are all different. The change only helps
by detecting equality, which is possible when a == a:

class Roo < Numeric; end
a = Roo.new

p [a,a].sort # [#<Roo:0x264a66c>, #<Roo:0x264a66c>]

- Better than:
"I can't sort these, I don't know what they are."

>
> >
> > * numeric.c (num_cmp): added to satisfy Comparable assumption.
>
> Hm... Doesn't sound as if the assumption was satisfied...
>

Nothing deep here, I think - just a tiny kink removed :-?


daz

Robert Klemme

unread,
Nov 10, 2005, 9:33:27 AM11/10/05
to
daz wrote:
> Robert Klemme wrote:
>> daz wrote:
>>>
>>> but it's able to tell that a == c which might
>>> be enough to keep a routine running.
>>
>> Definitely not:
>>
>>>> ar=(0..2).map { Roo.new }
>> => [#<Roo:0x101957e8>, #<Roo:0x101957b8>, #<Roo:0x10195788>]
>>>> ar.sort
>> ArgumentError: comparison of Roo with Roo failed
>
>
> Those instances are all different. The change only helps
> by detecting equality, which is possible when a == a:

But for detecting equality there's already == and eql?. And these methods
are used where equality is needed (namely in a hash). No need to have a
crippled <=>.

> class Roo < Numeric; end
> a = Roo.new
> p [a,a].sort # [#<Roo:0x264a66c>, #<Roo:0x264a66c>]
>
> - Better than:
> "I can't sort these, I don't know what they are."

I beg to differ: IMHO it's better to make this case raise an error because
that way it's more likely that a missing implementation of <=> is
detected.

>>> * numeric.c (num_cmp): added to satisfy Comparable assumption.
>>
>> Hm... Doesn't sound as if the assumption was satisfied...
>>
>
> Nothing deep here, I think - just a tiny kink removed :-?

Kind regards

robert

0 new messages