I think there is an optimization going on that doesn't use <=> for String
and subclasses. This is one of the reasons why it's subclassing of core
classes like String, Array etc. should be done rarely and with care.
In your case you better use sort_by:
a=["1","10","5"]
=> ["1", "10", "5"]
a.sort_by {|x| x.to_i}
=> ["1", "5", "10"]
This works also if the array contains instances of your subclass. It
might also be more efficient as #to_i is only invoked once per instance
and not once per comparison per compared object.
Then I wrote a class without String inheritance and it works.
BUT: another strange thing happened:
in `<=>': undefined method `to_i' for #<S:0x40020930 @a="10">
(NoMethodError)
to_i method, even if @a is a String, must be explicitely defined.
Moreover "defined". What do you think about it?
That's not strange. That's perfectly normal. Because there is no default #to_i method:
Object.new.to_i
NoMethodError: undefined method `to_i' for #<Object:0x101d0b28>
from (irb):3
from :0
In message "Re: Array.sort when it's items are String inheritors with redefined <=> works like if not redefined" on Wed, 19 Oct 2005 22:28:29 +0900, MiG <mig@1984.cz> writes:
Hello,
I want to have a string which, if in array, will be sorted like numbers.
I wrote this:
harp:~ > cat a.rb
class Array
def sort_as!
map!{|elem| yield elem}
sort!
self
end
def sort_as
dup.sort!
end
end
a = %w( 1 10 5 )
p a.sort_as{|s| Integer s}
p a.sort_as{|s| Float s}
p a.sort_as{|s| s.reverse }
a.sort_as!{|s| Integer s}
p a
harp:~ > ruby a.rb
["1", "10", "5"]
[1, 5, 10]
this avoids calling to_i, to_f, or whatever multiple times on the same object,
which will occur if you use either a spacship (<=>) operator or sort_by
approach.
hth.
-a
···
On Wed, 19 Oct 2005, MiG wrote:
Hello,
I want to have a string which, if in array, will be sorted like numbers. I wrote this:
a = [ String2.new('1'), String2.new('10'), String2.new('5') ]
puts a.sort.join(',')
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
anything that contradicts experience and logic should be abandoned.
-- h.h. the 14th dalai lama
I thought sort_by was a packaged form of the Schwartzian transform, i.e.
class A
def to_i
puts "in A.to_i"
3
end
end
p [1, 2, 3, 4, 5, A.new].sort_by {|x| x.to_i }
# is equivalent to
p [1, 2, 3, 4, 5, A.new].map{|x| [x.to_i, x]}.sort{|y, z| y[0] <=>
z[0]}.map{|x| x[1]}
__END__
in A.to_i
[1, 2, 3, #<A:0x2870f28>, 4, 5]
in A.to_i
[1, 2, 3, #<A:0x2870cd0>, 4, 5]
Regards,
Sean
···
On 10/19/05, Ara.T.Howard <Ara.T.Howard@noaa.gov> wrote:
this avoids calling to_i, to_f, or whatever multiple times on the same object,
which will occur if you use either a spacship (<=>) operator or sort_by
approach.
I'm not sure it is worth adding such a method, when a map{}.sort would
do the same thing, and is more explicit. Plus we have sort_by to solve
the OP's problem.
Ryan
···
On 10/19/05, Ara.T.Howard <Ara.T.Howard@noaa.gov> wrote:
In message "Re: Array.sort when it's items are String inheritors with redefined <=> works like if not redefined" on Wed, 19 Oct 2005 23:06:04 +0900, James Edward Gray II <james@grayproductions.net> writes:
a = ['1', '10', '5']
puts a.sort_by{|x|x.to_u}.join(',')
you are quite right sean - i guess that only applies to the op's original
a.to_i <=> b.to_i
where you could end up doing that more than once.
regards.
-a
···
On Wed, 19 Oct 2005, Sean O'Halpin wrote:
On 10/19/05, Ara.T.Howard <Ara.T.Howard@noaa.gov> wrote:
this avoids calling to_i, to_f, or whatever multiple times on the same object,
which will occur if you use either a spacship (<=>) operator or sort_by
approach.
I thought sort_by was a packaged form of the Schwartzian transform, i.e.
class A
def to_i
puts "in A.to_i"
3
end
end
p [1, 2, 3, 4, 5, A.new].sort_by {|x| x.to_i }
# is equivalent to
p [1, 2, 3, 4, 5, A.new].map{|x| [x.to_i, x]}.sort{|y, z| y[0] <=>
z[0]}.map{|x| x[1]}
__END__
in A.to_i
[1, 2, 3, #<A:0x2870f28>, 4, 5]
in A.to_i
[1, 2, 3, #<A:0x2870cd0>, 4, 5]
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
anything that contradicts experience and logic should be abandoned.
-- h.h. the 14th dalai lama