MiG wrote:
> Hello,
>   I want to have a string which, if in array, will be sorted like
> numbers
> I wrote this:
>
> ------------------------------------------------------------------------
-----------------
>
> class String2 < String
>
>      def <=> str2
>          self.to_i <=> str2.to_i
>      end
>
> end
>
> a = [ String2.new('1'), String2.new('10'), String2.new('5') ]
>
> puts a.sort.join(',')
>
> ------------------------------------------------------------------------
-----------------
>
> It produces "1,10,5", but I expected "1,5,10"

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

Kind regards

    robert