method_missing 和dynamically method资料总结

1.when&how:http://www.alfajango.com/blog/method_missing-a-rubyists-beautiful-mistress/

def method_missing(method_id, *arguments, &block)
  if method_id.to_s =~ /^what_is_[w]+/ # <1> get tested
    self.class.send :define_method, method_id do # <2> wrap it up
      # do your thing
    end
    self.send(method_id)
  else
    super # <3> clean up after yourself
  end
end

def respond_to?(method_id, include_private = false)
  if method_id.to_s =~ /^what_is_[w]+/
    true
  else
    super
  end
end # <4> tell the world

treat define_method as your faithful companion, method_missing as your passionate but careful mistress, and respond_to? as your love-child.

  1. http://rubylearning.com/blog/2010/10/07/do-you-know-rubys-chainsaw-method/

3. http://technicalpickles.com/posts/using-method_missing-and-respond_to-to-create-dynamic-methods/

respond_to? is used to determine if an object responds to a method. It is often used to check that an object knows about a method before actually calling it, in order to avoid an error at runtime about the method existing.
class LegislatorDynamicFinderMatch
  attr_accessor :attribute
  def initialize(method_sym)
    if method_sym.to_s =~ /^find_by_(.*)$/
      @attribute = $1.to_sym
    end
  end

  def match?
    !@attrbute.nil?
  end
end

class legislator
  def self.method_missing(method_sym, *args, &block)
    match = LegislatorDynamicFinderMatch.new(method_sym)
    if match.match?
      self.class.send :define_method, method_sym do
        find(match.attribute => args.first)
      end
      self.send(method_sym)
    else
      super
    end
  end

  def respond_to?(method_sym, include_private = false)
    if LegislatorDynamicFinderMatch.new(method_sym).match?
      true
    else
      super
    end
  end
end
 
class Legislator
  def self.method_missing(method_sym, *arguments, &block)
    match = LegislatorDynamicFinderMatch.new(method_sym)
    if match.match?
      define_dynamic_finder(method_sym, match.attribute)
      send(method_sym, arguments.first)
    else
      super
    end
  end

  protected

  def self.define_dynamic_finder(finder, attribute)
    class_eval <<-RUBY
      def self.#{finder}(#{attribute})        # def self.find_by_first_name(first_name)
        find(:#{attribute} => #{attribute})   #   find(:first_name => first_name)
      end                                     # end
    RUBY
  end
end

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注


*

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>