How to find where a method is defined at runtime?
This is really late, but here's how you can find where a method is defined:
http://gist.github.com/76951
# How to find out where a method comes from.
# Learned this from Dave Thomas while teaching Advanced Ruby Studio
# Makes the case for separating method definitions into
# modules, especially when enhancing built-in classes.
module Perpetrator
def crime
end
end
class Fixnum
include Perpetrator
end
p 2.method(:crime) # The "2" here is an instance of Fixnum.
#<Method: Fixnum(Perpetrator)#crime>
If you're on Ruby 1.9+, you can use source_location
require 'csv'
p CSV.new('string').method(:flock)
# => #<Method: CSV#flock>
CSV.new('string').method(:flock).source_location
# => ["/path/to/ruby/1.9.2-p290/lib/ruby/1.9.1/forwardable.rb", 180]
Note that this won't work on everything, like native compiled code. The Method class has some neat functions, too, like Method#owner which returns the file where the method is defined.
EDIT: Also see the __file__
and __line__
and notes for REE in the other answer, they're handy too. -- wg
Get the name of method at runtime
I assume this is Java... If that is the case, this returns the name of the method you are currently in.
String methodName = new Exception().getStackTrace()[0].getMethodName()
Be careful though, don't put this in a method, because then that will return the name of that method. You could also use this:
public String getMethodName() {
return new Exception().getStackTrace()[1].getMethodName();
}
This observes the second element of the stack trace, returning the correct method name.
UPDATE:
Though the first does what it takes, this is nicer: doesn't involve creating a new object at least:
Thread.currentThread.getStackTrace()[1].getMethodName();
Warning I have to mention that all this however has an adverse impact on performance...
Finding out where methods are defined in Ruby/Rails (as opposed to Java)
The Pry gem is designed precisely for this kind of explorative use-case.
Pry is an interactive shell that lets you navigate your way around a program's source-code using shell-like commands such as cd
and ls
.
You can pull the documentation for any method you encounter and even view the source code, including the native C code in some cases (with the pry-doc
plugin). You can even jump directly to the file/line where a particular method is defined with the edit-method
command. The show-method
and show-doc
commands also display the precise location of the method they're acting on.
Watch the railscast screencast for more information.
Here are some examples below:
pry(main)> show-doc OpenStruct#initialize
From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/ostruct.rb @ line 46:
Number of lines: 11
visibility: private
signature: initialize(hash=?)
Create a new OpenStruct object. The optional hash, if given, will
generate attributes and values. For example.
require 'ostruct'
hash = { "country" => "Australia", :population => 20_000_000 }
data = OpenStruct.new(hash)
p data # -> <OpenStruct country="Australia" population=20000000>
By default, the resulting OpenStruct object will have no attributes.
pry(main)>
You can also look up sourcecode with the show-method
command:
pry(main)> show-method OpenStruct#initialize
From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/ostruct.rb @ line 46:
Number of lines: 9
def initialize(hash=nil)
@table = {}
if hash
for k,v in hash
@table[k.to_sym] = v
new_ostruct_member(k)
end
end
end
pry(main)>
See http://pry.github.com for more information :)
How do I find where a Ruby method is called at runtime?
The suggestion to use caller()
is fine for figuring out the stack trace from a certain method. However, I'll also share (what I think is) the solution to your problem.
The to_s
method returns a string that is used to set an instance variable dynamically. The DetailsViewBuilder
's object_id
is part of the variable name. The object ID represents the object's location in memory. Contrary to intuition, the object_id
of an object may sometimes be negative integer. Whether or not this happens may also be platform-dependant. This explains why you are only seeing this error in production. The negative object ID causes the instance variable name to become something like @content_for_details_view_builder__-626960428
, which contains a dash. Dashes are not allowed as part of identifiers in Ruby. Hence the error.
It seems that you are using an instance of DetailsViewBuilder
as argument to content_for
somewhere, is that right? Or it might happen indirectly, in some library you are using.
In any case, if this is the correct behaviour, and all you want is to avoid the instance variable name error, then the fix is simple. Change object_id
to object_id.abs
to guarantee that the instance variable never contains a dash:
def to_s
"#{self.class.name.underscore}__#{object_id.abs}"
end
Ruby / Rails -- from where was a method was included?
Whatever context you're in you can get the source location by using:
obj.method(:method).source_location
It won't give you exactly what you want, but the Rails core developers are good about properly namespacing things. The following example can be run from the rails console:
Time.method(:zone).source_location
["/Users/pete/.rvm/gems/ruby-1.9.2-p290@gemset/gems/activesupport-3.2.3/lib/active_support/core_ext/time/zones.rb", 9]
Then you can go to the Rails source and search for that file. Hint: type 't' on Github and start typing. It will bring you to that file and you can see that it is defined directly on the Time class.
How to check if C++ abstract method is defined at runtime
As you can't instantiate an abstract class, any class you encounter at runtime will not have any pure virtual methods (unless you're in a constructor or destructor at the time), they'll all have been overriden with a non-pure overrider. There is nothing to check.
Related Topics
Why Does Ruby 1.9.2 Remove "." from Load_Path, and What's the Alternative
What Are All the Common Ways to Read a File in Ruby
How to Have Methods Inside Methods
Group Hashes by Keys and Sum the Values
Custom Authentication Strategy For Devise
Understanding Private Methods in Ruby
When Do Ruby Instance Variables Get Set
Ruby 1.9: Invalid Byte Sequence in Utf-8
Best Way to Create Custom Config Options For My Rails App
Calling a Method from a String With the Method'S Name in Ruby
Using Net::Http.Get For an Https Url