Fixnum <=> confusion

R

Robert Evans

Hi,

I am recently learning Ruby, and came across an interesting problem
that I do not understand. I was trying to count how many times the sort
method was called on an object by overridding <=> to count the number
of calls.

I decided to extend Fixnum as follows, but it didn't work. Can anyone
tell me why? Thanks.

Bob Evans


Code:

class Fixnum

@@count = 0

alias originalComparator <=>

def <=>(o)
@@count += 1
originalComparator(o)
end

def Fixnum.count
@@count
end
end

Running against it:
array = [5, 4, 3, 2, 1]
=> [5,4,3,2,1]
array.sort
=> [1,2,3,4,5]
Integer.count
=> 0

Expected => 6 > result > 0

Now, if I call 1<=>2 then count increments. Does this mean that Fixnum
sorting does not call those operators? Thanks for any help.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Fixnum <=> confusion"

|Now, if I call 1<=>2 then count increments. Does this mean that Fixnum
|sorting does not call those operators? Thanks for any help.

sort skips <=> calls for fixnums to gain performance.

matz.
 
B

Brian Candler

Now, if I call 1<=>2 then count increments. Does this mean that Fixnum
sorting does not call those operators? Thanks for any help.

Use The Source, Luke :)

$ cd /v/build/ruby/ruby-1.8.1-2004.05.02/
$ less array.c

static int
sort_2(ap, bp)
...
if (FIXNUM_P(a) && FIXNUM_P(b)) {
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
if (TYPE(a) == T_STRING && TYPE(b) == T_STRING) {
return rb_str_cmp(a, b);
}
...
static VALUE
sort_internal(ary)
VALUE ary;
{
qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),
rb_block_given_p()?sort_1:sort_2);
return ary;
}

In other words: Array#sort, when called without a block, special-cases the
comparison of Fixnum to Fixnum and String to String, doing a hard-coded test
instead of calling the spaceship operator.

Try doing:
array.sort { |a,b| a<=>b }
to force it to do the method call.

Regards,

Brian.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top