Hacker News new | past | comments | ask | show | jobs | submit login
AbstractQueryFactoryFactories and alias_method_chain: The Ruby Way (yehudakatz.com)
42 points by wycats on Feb 15, 2010 | hide | past | favorite | 9 comments



I've always thought that alias_method was a pretty silly way to solve the problem of defining a new method in terms of an existing method with the same name. alias_method is definitely "simpler", but I think the way it actually destructively creates a method in a class is a bit ugly. I don't know what "AbstractQueryFactoryFactories" are, but the name makes me want to stay pretty far away from them.

These monkey patches constitute my solution to the problem:

    class UnboundMethod
      def origin
        owner.instance_method(name)
      end
    end
    
    class Proc
      def to_method(object, method)
        me = self
        object.class.class_eval do
          current = instance_method(method).origin rescue nil
          mine = current.owner == self rescue false
          define_method(method, &me)
          result = instance_method(method)
          mine ? define_method(method, current) : remove_method(method)
          result
        end.bind(object)
      end
    end
    
    class Module
      def redefine(method, &code)
        original = instance_method(method).origin
        define_method(method) do |*args, &block|
          code.to_method(self, method).(original.bind(self), *args, &block)
        end
      end
    end
You use this as follows:

    Fixnum.redefine(:+) do |old_plus, other|
      if self == 2 and other == 2
        5
      else
        old_plus.(other)
      end
    end

    >> 2 + 2
    => 5
    >> 2 + 3
    => 5
    >> 2 + 1
    => 3
I'll admit that its implementation is pretty horrible, but I think the interface is much nicer: you pass in a function which specifies your new function in terms of the old one, which is always passed as the first argument.


You're actually reimplementing some parts of Ruby that already exist: http://ruby-doc.org/core-1.8.7/classes/UnboundMethod.html


Sorry, I'm not sure what you mean. What did I implement that already exists? The only method I added to UnboundMethod was origin, and I don't see a method on that page that does that.


Err... apologies. I thought you were unaware of the UnboundMethod class.


I'm glad someone responded to the original post, after so many years of java, I can't really say I ever enjoyed factories they always seemed to solve a problem that was a weakness in the language itself.


I'm surprised anyone bothered; the original post was so very obviously troll bait. People who've been in the Ruby community as long as Yehuda should know better.


Good writeup but it could have been more useful if he showed the equivalent Java code.


The equivalent Java code is in the original post he's responding to.


It's Scala code.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: