How do you know what class defines method foo()?

S

Sam Kong

Hi, folks!

What's the easiest(simplest) code to find a class/module that first
defines a specific method?
I became curious while I was looking for a document of Array#partition
method.
Actually the method is defined in Enumerable module.
But I couldn't guess that it was defined there until I checked Array
class's doc first.
If the inheritance(or mixin) hierarchy is very complex, it will take
long to find a method.

The one I can think of is using MyClass.ancestors and
MyClass.instance_methods recursively (or repeatedly).
Is there a better way?
(On my second thought, singleton classes should also be considered,
right?)

The method prototype might be like...

#returns a class or module which defines the method
def defined_where(obj, method_name)
...
end

Thanks.

Sam
 
J

Joe Van Dyk

Hi, folks!

What's the easiest(simplest) code to find a class/module that first
defines a specific method?

$ ri partition

--------------------------------------------------- Enumerable#partition
enum.partition {| obj | block } =3D> [ true_array, false_array ]
 
L

Logan Capaldo

Hi, folks!

What's the easiest(simplest) code to find a class/module that first
defines a specific method?
I became curious while I was looking for a document of Array#partition
method.
Actually the method is defined in Enumerable module.
But I couldn't guess that it was defined there until I checked Array
class's doc first.
If the inheritance(or mixin) hierarchy is very complex, it will take
long to find a method.

The one I can think of is using MyClass.ancestors and
MyClass.instance_methods recursively (or repeatedly).
Is there a better way?
(On my second thought, singleton classes should also be considered,
right?)

The method prototype might be like...

#returns a class or module which defines the method
def defined_where(obj, method_name)
...
end

Thanks.

Sam



Array.method_defined?:)partition)
#=> true

Enumerable.method_defined?:)partition)
#=> true

Same for instance_methods.include?.
If we loop forward through ancestors, we get Array as the answer. If
we loop backwards we get Enumerable. The problem is, looping
backwards will get us the wrong answer if Array overrides partition.
I can't think of a good why to do this unless there is a
Class#overrides? method. (e.g. Array.overrides?:)partition) #=> false ).
 
D

Dominik Bathon

Array.method_defined?:)partition)
#=3D> true

Enumerable.method_defined?:)partition)
#=3D> true

Same for instance_methods.include?.
If we loop forward through ancestors, we get Array as the answer. If we= =20
loop backwards we get Enumerable. The problem is, looping backwards wil= l =20
get us the wrong answer if Array overrides partition. I can't think of = a =20
good why to do this unless there is a Class#overrides? method. (e.g. =20
Array.overrides?:)partition) #=3D> false ).

I just played a bit around and found Method#inspect:
a =3D [] =3D> []
a.method:)partition)
=3D> # said:
a.method:)first)
=3D> # said:
a.method:)send)
=3D> # said:
class Array; def send *a; super end end =3D> nil
a.method:)send)
=3D> #<Method: Array#send>

So, if just want to know it for one case, use irb and look at =20
Method#inspect.

To write a method that returns the class/module that defines a method one=
=20
might parse the output of Method#inspect, but I think that is not very =20
nice.

There doesn't seem to be a direct way to get the class/module in Ruby.


Dominik
 
S

Sam Kong

So, if just want to know it for one case, use irb and look at
Method#inspect.

To write a method that returns the class/module that defines a method one
might parse the output of Method#inspect, but I think that is not very
nice.

This is exactly what I wanted.
I didn't know that there's 'method' method.
Thank you very much.

Sam
 
F

Florian Groß

Dominik said:
To write a method that returns the class/module that defines a method
one might parse the output of Method#inspect, but I think that is not
very nice.

There doesn't seem to be a direct way to get the class/module in Ruby.

But there ought to be. If you think so as well please vote on this RCR:

http://www.rcrchive.net/rcr/show/292
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top