How to find where a method is defined

Hi all,

Now I am learning Ruby on Rails and have a problem.
I know here isn't Ruby on Rails ML, but my question has some relations
to ruby's topic, I think.

If you know Rails, you also know that some classes can be generated by
using rails command like this:

rails generate controller hello

I created a file named hello_controller.rb and modifiedits code as bellow:

···

------------------------------------------
class HelloController < ApplicationController
def index
render :text => 'hello world'
end
end
--------------------------------------------

In the above I used the method named 'render', butI didn't know where it
was defined. So I modified the program further like this:
----------------------------------------------
class HelloController < ApplicationController

def index
#class name
@controller_name = self.class.to_s

#module names included by this class
included_modules = self.class.included_modules

#get the names of each super class
@ancestors = self.class.ancestors
ancestor_classes = @ancestors - included_modules
#get the method names of each classes
@ancestor_classes =
ancestor_classes.map{|ac|
[ac, [eval("#{ac}.class.public_instance_methods"),
eval("#{ac}.class.protected_instance_methods"),
eval("#{ac}.class.private_instance_methods")]]
}
#get the names of each module
@included_modules =
included_modules.map{|im|
[im, [eval("#{im}.class.public_instance_methods"),
eval("#{im}.class.protected_instance_methods"),
eval("#{im}.class.private_instance_methods")]]
}

@included_modules.delete_if{|e| e[1][0] == nil}
end
end
------------------------------------------

What I intended to do was to collect the method names of each
class/module into the vareable named @ancestor_classes and
included_modules, respectively.
As the result, however, I couldn't find any methods named 'render'.What
is wrong in the above code? I'm really confused about this because I
thought it was the best way to use Module#public_instance_methods,
Module#protected_instance_methods and Module#private_instance_methods to
find the definitions of methods in superclasses and included modules.

In general, what is the right way to find the methods by tracing modules
and superclasses?I would very much appreciate any helps and advice.

My environment is:
OS:Windows7
ruby 1.9.3p194
Rails 3.2.8

*)I did make sure the result by making so called view
class file(erb) as bellow:
---------------------------------------------
<h1><%=@controller_name -%>Classes</h1>
<ul>
<% @ancestor_classes.each do |ac| %>
<li>
<h2><%= ac[0] %></h2>
<dl>
<dt>public methods</dt>
<dd>
<ul>
<% ac[1][0].each do |method| %>
<li><%= method %></li>
<% end %>
</ul>
</dd>
<dt>protected methods</dt>
<dd>
<ul>
<% ac[1][1].each do |method| %>
<li><%= method %></li>
<% end %>
</ul>
</dd>
<dt>private methods</dt>
<dd>
<ul>
<% ac[1][2].each do |method| %>
<li><%= method %></li>
<% end %>
</ul>
</dd>
</dl>
</li>
<% end %>
</ul>
<h1><%=@controller_name -%>included modules</h1>
<ul>
<% @included_modules.each do |im| %>
<li>
<h2><%= im[0] %></h2>
<dl>
<dt>public methods</dt>
<dd>
<ul>
<% im[1][0].each do |method| %>
<li><%= method %></li>
<% end %>
</ul>
</dd>
<dt>protected methods</dt>
<dd>
<ul>
<% im[1][1].each do |method| %>
<li><%= method %></li>
<% end %>
</ul>
</dd>
<dt>private methods</dt>
<dd>
<ul>
<% im[1][2].each do |method| %>
<li><%= method %></li>
<% end %>
</ul>
</dd>
</dl>
</li>
<% end %>
</ul>
---------------------------------------------

I created a file named hello_controller.rb and modifiedits code as bellow:
------------------------------------------
class HelloController < ApplicationController
def index
render :text => 'hello world'
end
end
--------------------------------------------

In the above I used the method named 'render', butI didn't know where it
was defined. So I modified the program further like this:

[...lots of code to replicate how ruby finds methods...]

it's a lot easier than that. That's basically what ruby does when it is trying to execute a method. Instead, grab the method you want and ask it:

10001 % ruby19 -S irb

class X; def x; end; end
class Y < X; def y; p method(:x).source_location; end; end
Y.new.y

["(irb)", 1]

Not the best example, of course, but you get the idea.

···

On Oct 14, 2012, at 22:13 , 前川 享仁 <takanobu_maekawa@pure-system.com> wrote:

What I intended to do was to collect the method names of each
class/module into the vareable named @ancestor_classes and
included_modules, respectively.

That's not a good idea IMHO since the data is redundant and you need
this for debugging / investigative purposes only anyway.

As the result, however, I couldn't find any methods named 'render'.What
is wrong in the above code? I'm really confused about this because I
thought it was the best way to use Module#public_instance_methods,
Module#protected_instance_methods and Module#private_instance_methods to
find the definitions of methods in superclasses and included modules.

In general, what is the right way to find the methods by tracing modules
and superclasses?I would very much appreciate any helps and advice.

Just access the method and output it with p:

$ ruby -e 'class X < Array; end;o = X.new; p o.method(:size)'
#<Method: X(Array)#length>

You'll see the defining class in brackets. You can also access it explicitly:

$ ruby -e 'class X < Array; end;o = X.new; p o.method(:size).owner'
Array

Kind regards

robert

···

On Mon, Oct 15, 2012 at 7:13 AM, 前川 享仁 <takanobu_maekawa@pure-system.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/