Martin DeMello wrote:

> Still hacky, but general:
> 
> class Test
>   attr_accessor :foo, :bar
>   def initialize(f, b)
>     @foo, @bar = f, b
>   end
> 
>   def inspect
>     "[#{foo}, #{bar}]"
>   end
> end
> 
> def rev(obj)
>   a = obj.dup
>   class << a
>     alias old_cmp <=>
>     def <=>(other)
>       -old_cmp(other)
>     end
>   end
>   a
> end
> 
> a = [
>   Test.new("Hello", 1),
>   Test.new("World", -1),
>   Test.new("Foo", 5),
>   Test.new("bar", 4)
> ]
> 
> p a
> p a.sort_by {|x| x.foo}
> p a.sort_by {|x| rev(x.foo)}

However, if we try 

   p a.sort_by { |x| rev(x.bar) }

we get ...

   sort_by.rb:20:in `dup': can't dup Fixnum (TypeError)

I tried sticking in an

   if obj.respond_to? :dup

but that didn't help.  It would appear that, while Fixnum responds to #dup, its response is "I'm sorry, Dave, I'm afraid I can't do that." :-(.

That doesn't seem to make a lot of sense to me.  I would have thought it made more sense for Fixnum#dup to just return self.  Maybe there's some good reason for not doing that.

Alternatively, maybe we need a way for classes to disown methods they inherit that they don't want to (or logically shouldn't) implement?  Then, Fixnum could disown dup and the respond_to? test would work the way I was expecting.

Harry O.