[Q] Array not Comparable?

In the past I have sorted arrays of arrays and so I knew that Array
implemented the spaceship operator (<=>), since sort uses that operator
to perform the sort. I also knew that the Comparable mixin requires
only that a class implement the spaceship operator. Somewhere in there,
I guess I just assumed that Array included Comparable, but apparently it
doesn’t.

This came up in a routine where I was trying to find the "best"

element in a list. There were three qualities that I was using to
determine “bestness”: quality1, quality2, and quality3. Eventually I
got down to the line where I need to decide if the current word is
"better" than my current “best”. The condition started to look like:

if (quality1 > maxquality1) ||
((quality1 == maxquality1) && (quality2 > maxquality2)) ||
((quality1 == maxquality1) && (quality2 == maxquality2) &&
(quality3 > maxquality3))

I realized that I could simplify this entire mess into something

clear, concise, and expandable (adding new qualities) by using arrays:

if [quality1,quality2,quality3] > [maxquality1,maxquality2,maxquality3]

However, since Array does not include Comparable, this throws an

error. Now, I can open the Array class myself and include Comparable
and this begins working just fine. Alternately, I could invoke the
spaceship operator instead of the less than operator and check for a
result of 1. But neither of these is as elegant as the original.

So, my questions are:

1) Is there a reason for Array to NOT include Comparable even though

the spaceship operator is defined?
2) If not, can this be included in future versions?
3) If so, do I need to submit an RCR?
4) Is there some other concise way to achieve what I am trying to
do?

Thanks in advance,

- Warren Brown

Warren Brown wrote:

So, my questions are:

  1. Is there a reason for Array to NOT include Comparable even though
    the spaceship operator is defined?
  2. If not, can this be included in future versions?
  3. If so, do I need to submit an RCR?
  4. Is there some other concise way to achieve what I am trying to
    do?

i’m surprised nobody answers this. a quick google doesn’t find anything
on this. i find this very interesting too…

emmanuel

i'm surprised nobody answers this. a quick google doesn't find anything
on this. i find this very interesting too..

[ruby-talk:22363]

Guy Decoux

i’m surprised nobody answers this. a quick google doesn’t find anything
on this. i find this very interesting too…

[ruby-talk:22363]

Quoting from that ref:

Good. By the way, when will Array include Comparable ?

They won’t. Arrays are not comparable in general. They are
comparable only when all of their elements are comparable.

                                                  matz.

A. “Arrays are not comparable in general.”
B. Array implements <=>.

Seems like a contradiction to me.

Gavin

···

On Wednesday, October 22, 2003, 11:49:17 PM, ts wrote:

A. "Arrays are not comparable in general."
B. Array implements <=>.

Seems like a contradiction to me.

Well, if you look at the classes which include Comparable you'll see that
#<=> return (-1, 0, 1) when the 2 objects are in the same class (this is
simplified, see for example String#<=>)

This is not the case for Array

svg% ruby -e 'p ([1, "a"] <=> [1, 2])'
nil
svg%

You have 2 arrays, but ruby can't compare these objects

Guy Decoux

So:

class Array
include Comparable
end

[1, 3] > [1, 2] # true
[1, “a”] > [1, 2] # ArgumentError: comparison of Array with Array failed

Seems logical to me.

Gavin

···

On Thursday, October 23, 2003, 12:40:50 AM, ts wrote:

A. “Arrays are not comparable in general.”
B. Array implements <=>.

Seems like a contradiction to me.

Well, if you look at the classes which include Comparable you’ll see that
#<=> return (-1, 0, 1) when the 2 objects are in the same class (this is
simplified, see for example String#<=>)

This is not the case for Array

svg% ruby -e ‘p ([1, “a”] <=> [1, 2])’
nil
svg%

You have 2 arrays, but ruby can’t compare these objects

Guy,

svg% ruby -e ‘p ([1, “a”] <=> [1, 2])’
nil
svg%

I see your point, but:

%ruby -e ‘p [[1],[2]].sort’

[[1], [2]]
%ruby -e ‘p [[1],[“a”]].sort’
-e:1:in `sort’: comparison of Array with Array failed (ArgumentError)
from -e:1

So why have Array#sort allow comparisons where possible (throwing an

error where it is not), but not allow comparison operators to do the
same?

irb(main):001:0> class Array
irb(main):002:1> include Comparable
irb(main):003:1> end
=> Array
irb(main):004:0> [1] < [2]
=> true
irb(main):005:0> [1] < [‘a’]
ArgumentError: comparison of Array with Array failed
from (irb):5:in `<’
from (irb):5

This seems more consistent to me.  Anyone else?

- Warren Brown

Seems logical to me.

You find logical to say that 2 arrays are comparable (this is, in sort,
what you say when you include Comparable) and then give an error
to say that it's not possible to compare 2 arrays ?

You must be an "anglois" :slight_smile:

Guy Decoux

    So why have Array#sort allow comparisons where possible (throwing an
error where it is not), but not allow comparison operators to do the
same?

ruby give you the possibility to sort an array, but it don't say that 2
arrays are comparable, precisely because it exist case when it can't
compare 2 arrays.

    This seems more consistent to me. Anyone else?

See [ruby-talk:84370]

Guy Decoux