对象#方法和动态响应者

Mat*_*ins 5 ruby method-missing

我有一个Ruby对象(特别是一个ActiveRecord对象)User.它响应像find_by_id,find_by_auth_token等等方法.但是,这些不是通过def或定义的方法define_method.相反,它们是通过处理的动态方法method_missing.

我想通过以下方式获得对这些方法之一的引用Object#method:

User.method(:find_by_auth_token)
Run Code Online (Sandbox Code Playgroud)

虽然看起来不像这样.我提出的最佳解决方案是:

proc { |token| User.find_by_auth_token(token) }
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以使用这样的包装方法?我真的无法Object#method用于动态方法吗?

pje*_*pje 5

最简单的答案是"不",以保证-The唯一方法一般Object#method(:foo)将返回的实例Method定义了一个名为方法是foo在对象上.

更复杂的答案是你可以通过覆盖Object#method(:foo)返回一个实例来强制返回给定的返回.例如:MethodObject#respond_to_missing?true:foo

class User
  def respond_to_missing?(method_name, include_private = false)
    method_name.to_s.start_with?('find_by_')
  end
end

m = User.new.method(:find_by_hackish_means)
# => #<Method: User#find_by_hackish_means>
Run Code Online (Sandbox Code Playgroud)

(这取决于您确保实际定义该方法):

m.call
# => NoMethodError: undefined method `find_by_hackish_means' for #<User:0x123>
Run Code Online (Sandbox Code Playgroud)

  • 这是一篇关于这个主题的更深入的博客文章:http://robots.thoughtbot.com/post/28335346416/always-define-respond-to-missing-when-overriding (2认同)