Frage

I have a Ruby object (an ActiveRecord object, specifically) named User. It responds to methods like find_by_id, find_by_auth_token, etc. However, these aren't methods that are defined via def or define_method. Instead, they are dynamic methods that are handled via method_missing.

I'd like to obtain a reference to one of these methods via Object#method, e.g.:

User.method(:find_by_auth_token)

It doesn't look like this works though. The best solution I've come up with is:

proc { |token| User.find_by_auth_token(token) }

Is there any other way around using such a wrapper method as this? Am I really unable to use Object#method for dynamic methods?

War es hilfreich?

Lösung

The simplest answer is "no"—the only way to guarantee in general that Object#method(:foo) will return an instance of Method is by defining a method named foo on the object.

The more complected answer is that you can coerce Object#method(:foo) into returning an instance of Method by overriding Object#respond_to_missing? s.t. it returns true when given :foo. For example:

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>

(It's up to you to ensure that the method is actually defined):

m.call
# => NoMethodError: undefined method `find_by_hackish_means' for #<User:0x123>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top