How to dynamically create instance methods at runtime?

前端 未结 3 1681
旧时难觅i
旧时难觅i 2021-01-17 18:08

[ruby 1.8]

Assume I have:

dummy \"string\" do
    puts \"thing\" 
end

Now, this is a call to a method which has as

3条回答
  •  感动是毒
    2021-01-17 18:40

    I'm particularly fond of using method_missing, especially when the code you want to use is very similar across the various method calls. Here's an example from this site - whenever somebody calls x.boo and boo doesn't exist, method_missing is called with boo, the arguments to boo, and (optionally) a block:

    class ActiveRecord::Base
      def method_missing(meth, *args, &block)
        if meth.to_s =~ /^find_by_(.+)$/
          run_find_by_method($1, *args, &block)
        else
          super # You *must* call super if you don't handle the
                # method, otherwise you'll mess up Ruby's method
                # lookup.
        end
      end
    
      def run_find_by_method(attrs, *args, &block)
        # Make an array of attribute names
        attrs = attrs.split('_and_')
    
        # #transpose will zip the two arrays together like so:
        #   [[:a, :b, :c], [1, 2, 3]].transpose
        #   # => [[:a, 1], [:b, 2], [:c, 3]]
        attrs_with_args = [attrs, args].transpose
    
        # Hash[] will take the passed associative array and turn it
        # into a hash like so:
        #   Hash[[[:a, 2], [:b, 4]]] # => { :a => 2, :b => 4 }
        conditions = Hash[attrs_with_args]
    
        # #where and #all are new AREL goodness that will find all
        # records matching our conditions
        where(conditions).all
      end
    end
    

    define_method also looks like it would work for you, but I have less experience with it than method_missing. Here's the example from the same link:

    %w(user email food).each do |meth|
      define_method(meth) { @data[meth.to_sym] }
    end
    

提交回复
热议问题