Eric Hodel wrote:
> somethings.sort_by { |s| s.sort_obj }

Since this is more efficient than #sort, maybe the implementation of 
#sort should first try to do this, and only if that fails (#sort_obj not 
defined, or two sort_obj not comparable), revert to the normal <=> 
algorithm.

This would make a difference when some library does a #sort on some 
collection, and you can't tell it to #sort_by instead (and you can't 
redefine #sort in the collection, either).

In the cases where you have a collection of objects that don't respond 
to #sort_obj, #sort will quickly hit a failure and use the fall-back. 
(The worst case would be if, say, all but the last object in the 
collection had #sort_obj.)

It should also fall back if <=> fails on the sort objs. I'm not sure how 
to detect that reliably though.

Anyway, here's a half-baked attempt:

class NoSortObjMethod < StandardError; end

class Object
   def sort_obj
     raise NoSortObjMethod
   end
end

class Array
   alias old_sort sort
   def sort
     if block_given?
       old_sort {|*args| yield(*args)}
     else
       begin
         rslt = sort_by {|s| s.sort_obj}
         puts "DEBUG: used sort_by with sort_obj"
         rslt
       rescue NoSortObjMethod
         puts "DEBUG: NoSortObjMethod, using old_sort"
         old_sort
       rescue TypeError => ex # ?
         puts "DEBUG: Comparison failed (#{ex}), using old_sort"
         old_sort
       end
     end
   end
end

a = [1, 3, 2]
p a
p a.sort


class C
   def initialize n
     @n = n
   end

   def sort_obj
     @n
   end
end

b = [C.new(1), C.new(3), C.new(2)]
p b
p b.sort

__END__

Output:

[1, 3, 2]
DEBUG: NoSortObjMethod, using old_sort
[1, 2, 3]
[#<C:0xb7c3d248 @n=1>, #<C:0xb7c3d234 @n=3>, #<C:0xb7c3d220 @n=2>]
DEBUG: used sort_by with sort_obj
[#<C:0xb7c3d248 @n=1>, #<C:0xb7c3d220 @n=2>, #<C:0xb7c3d234 @n=3>]

-- 
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407