Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object#method and dynamic responders

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?

like image 247
Matt Huggins Avatar asked Sep 22 '12 13:09

Matt Huggins


People also ask

What do you mean of object?

1 : something material that may be perceived by the senses. 2 : something mental or physical toward which thought, feeling, or action is directed. object. noun. ob·​ject | \ ˈäb-jikt \

What is object and example?

An object is a noun (or pronoun) that is acted upon by a verb or a preposition. There are three kinds of object: Direct Object (e.g., I know him.) Indirect Object (e.g., Give her the prize.) Object of a Preposition (e.g., Sit with them.)

What are objects give five examples?

Look around right now and you'll find many examples of real-world objects: your dog, your desk, your television set, your bicycle. Real-world objects share two characteristics: They all have state and behavior. Dogs have state (name, color, breed, hungry) and behavior (barking, fetching, wagging tail).


1 Answers

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>
like image 50
pje Avatar answered Oct 29 '22 17:10

pje