Hi --

On Sun, 3 Dec 2006, chen li wrote:

>
> --- Martin DeMello <martindemello / gmail.com> wrote:
>>
>> sort_by is your friend. I don't have a windows
>> machine handy to
>> experiment, but say an Rows:WIN32OLE_METHOD defines
>> a #name, you can
>> say
>>
>> p m.sort_by {|i| i.name}
>>
>> or even
>>
>> m.map {|i| i.name}.sort
>>
>> if what you want is the names, rather than the
>> Rows:WIN32OLE_METHOD
>> objects themselves.
>>
>> Of course, if you *can* print it, it evidently
>> defines to_s and
>> inspect methods, so this will work:
>>
>> puts m.map {|i| i.to_s}.sort
>>
>> or
>>
>> puts m.map {|i| i.inspect}.sort
>>
>> martin
>
> Thanks and all of them work. But I just don't
> understand why the line code below works
>
> p m.sort_by {|i| i.name}
>
> yet p m.sort.each{|i| i.name} FAILS.

sort and sort_by work by comparing pairs of objects using the <=>
("spaceship") method.  So in your second example, you're asking Ruby
to do this:

   object1 <=> object2   # etc.

The problem is (I assume) that these objects don't have a <=> method.

However, if you compare by name, you're doing:

   object1.name <=> object2.name

Since names are strings, they *do* have a <=> method, so the
comparison can take place.

You can always define <=> for your class:

   class C
     attr_accessor :name
     def <=>(other)
       self.name <=> other.name
     end
   end

There's another issue, though.  Here:

   m.sort.each{|i| i.name}

I don't think you really want each.  each returns its receiver, so
that snippet is functionally equivalent to:

   m.sort

If you want to grab all the names in a new array, you would use map
rather than each.


David

-- 
                   David A. Black | dblack / wobblini.net
Author of "Ruby for Rails"   [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog)        [2] | Co-director, Ruby Central, Inc.   [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com    | [4] http://www.rubycentral.org