Numeric <=>

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

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

···

On Nov 8, 2005, at 12:52 PM, ChrisH wrote:

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?

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

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

Selon ChrisH <chris.hulan@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.

Christophe Grandsire wrote:

Selon ChrisH <chris.hulan@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

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

···

On Nov 9, 2005, at 8:47 AM, Robert Klemme wrote:

Christophe Grandsire wrote:

Selon ChrisH <chris.hulan@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...

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

Robert Klemme wrote:

···

Christophe Grandsire wrote:
> Selon ChrisH:
>
>> 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...

#-------------
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 <matz@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

daz wrote:

Robert Klemme wrote:

Christophe Grandsire wrote:

Selon ChrisH:

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...

#-------------
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.

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

Roo.new < Roo.new

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

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

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

<Changelog>

* 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

···

from :0
        from :0
        from :0
        from :0

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

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

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