Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List all methods that an object respond_to?

I have two models,

User 
Membership

The two have the following relationship with one another

user has_many :memberships

I've been trying to figure out where the build method resides, and how do i get it in a list of methods for the instance. Here is the output of the debugger that shows my delima

(rdb:63) @user.memberships.respond_to?"build"
true

While the following is returning false, shouldnt it return true??

(rdb:63) @user.memberships.instance_methods.include?"build"
false
like image 442
Syed Ali Avatar asked Apr 13 '11 15:04

Syed Ali


2 Answers

One point is that instance_methods takes an optional boolean parameter, indicating whether you want to see methods of the instances ancestors. In your case I think you want instance_methods(true).

However, it appears that "build" is an autogenerated method, according to the documentation. Typically the autogenerated methods in ActiveRecord are implemented by overriding method_missing and handling calls to "methods" that don't actually exist. responds_to is also overridden so that the class will indicate that it responds to the correct calls. However, since those "methods" aren't actually defined, they won't show up in the instance_methods list.

Since the list of commands that a class can respond_to using method_missing is essentially infinite, I'm pretty sure there's no way to get the list. For example, an ActiveRecord model that has attributes a,b,c, and d will automatically respond to calls such as find_by_a_and_b and find_by_a_b_and_c and find_by_b_and_d and so forth, ad infinitum. There's no way to get a list of all of those possibilities.

like image 192
Jacob Mattison Avatar answered Oct 15 '22 04:10

Jacob Mattison


Please note that instance_methods returns an array of String or Symbol depending on the Ruby version.

Ruby 1.8 returns an Array of String, Ruby 1.9 an Array of Symbol.

In Ruby 1.8

"".respond_to?(:upcase)
# => true 
"".class.instance_methods.include?("upcase")
# => false
"".class.instance_methods.include?(:upcase)
# => false

In Ruby 1.9

"".respond_to?(:upcase)
# => true 
"".class.instance_methods.include?("upcase")
# => false
"".class.instance_methods.include?(:upcase)
# => true

Also, instance_methods must be called on the class, not on the instance.

like image 5
Simone Carletti Avatar answered Oct 15 '22 03:10

Simone Carletti