Joel VanderWerf
10/7/2007 9:00:00 PM
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