This is a ruby C extension that defines a global method named current_iseq
.
It returns the instruction sequence of the context it was called from.
I couldn't find any other way to get a reference to the method being called
from within the method itself. The closest you can get is probably __callee__
which just gives you the name of the method. There's no guarantee that
getting a method object using something like method(__callee__)
will actually
give you the method it's being called from.
For example, suppose I want to get a reference to a method that's temporarily bound to another object:
# Note: I do not actually care about or want a reference to C#foo()
class C
def foo
:original
end
end
# Note: I DO want to get a reference to M#foo() from within the method itself.
# I will attempt to use `method(__callee__)` which is the same as using
# `method(:foo)` in this case.
module M
def foo
method(__callee__)
end
end
But what if I only temporarily bind M#foo()
to an instance of C?
method_object = M.instance_method(:foo).bind(C.new)
method_object.call
#=> #<Method: C#foo() foo.rb:2>
It gives me C#foo()
! That's not what I wanted :(
Now I can do this instead and at least get a reference to the instruction sequence of M#foo()
module M
def foo
current_iseq
end
end
puts M.instance_method(:foo).bind(C.new).call.disasm
Output:
== disasm: #<ISeq:[email protected]:10 (10,2)-(12,5)> (catch: FALSE)
0000 putself ( 11)[LiCa]
0001 opt_send_without_block <calldata!mid:current_iseq, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0003 leave ( 12)[Re]
For now this is just a quick test. You'll have to actually generate the makefile and run make.
$ ruby extconf.rb && make
creating Makefile
linking shared-object current_iseq.bundle
Then require 'current_iseq' from that directory.