Reputation: 1157
If we call caller
method, we get something like:
prog.rb:3:in `a'
prog.rb:6:in `b'
prog.rb:9:in `c'
This is helpful for humans, but if I wanted to analyze the stack programmatically, not really, as two methods called :a
may be entirely unrelated.
Is there any way/method to extract information about the receiver of the methods (like its class or object id) as well? For example:
prog.rb:3:in `Klass#a'
prog.rb:6:in `Modoole#b'
prog.rb:9:in `OtherKlass#c'
Formatting is only an example; this info might be an Array
or anything.
I'm trying to emulate this with TracePoint
, but forming a separate stack is a bad solution. Is there any Ruby way I missed in the docs?
Upvotes: 2
Views: 254
Reputation: 8777
There's an alternative to Kernel#caller
named Kernel#caller_locations
, that returns an array of Thread::Backtrace::Location
objects. According to the manual, these should in theory be able to give you this information through the #label
method.
Returns the label of this frame.
Usually consists of method, class, module, etc names with decoration.
After trying this out however, I need to question the term usually in the docs, because it seems to only return the method name still. Unless usually means it works for you, there seems to be no way of accomplishing this as of now.
Edit:
As per comment, one case that satisfies the condition of usually is when the method call is coming from within a Class
or Module
body:
class A
def trace
puts caller_locations.first.label
end
end
class B
A.new.trace
end
#=> <class:B>
module C
A.new.trace
end
#=> <module:C>
Upvotes: 1