There is an implementation in the Extensions gem, but it must be the last method call in the method, and we must use the binding within a block.
There is another implementation here, but it depends on tracing along all the code execution, compromising the performance.
However, in this answer in StackOverflow, Taisuke Yamada implemented an version of
ppp.rb
(what is it?) which inspired me to implement my own version of a caller_binding
method. Enjoy!#!/usr/bin/ruby # # (c) Sony Fermino dos Santos, 2011 # License: Public domain # Implementation: 2011-07-30 # # Published at: # http://rubychallenger.blogspot.com/2011/07/caller-binding.html # # Inspired on: # http://stackoverflow.com/questions/1356749/can-you-eval-code-in-the-context-of-a-caller-in-ruby/6109886#6109886 # # How to use: # return unless bnd = caller_binding # After that line, bnd will contain the binding of caller require 'continuation' if RUBY_VERSION >= '1.9.0' def caller_binding cc = nil # must be present to work within lambda count = 0 # counter of returns set_trace_func lambda { |event, file, lineno, id, binding, klass| # First return gets to the caller of this method # (which already know its own binding). # Second return gets to the caller of the caller. # That's we want! if count == 2 set_trace_func nil # Will return the binding to the callcc below. cc.call binding elsif event == "return" count += 1 end } # First time it'll set the cc and return nil to the caller. # So it's important to the caller to return again # if it gets nil, then we get the second return. # Second time it'll return the binding. return callcc { |cont| cc = cont } end # Example of use: def var_dump *vars return unless bnd = caller_binding vars.each do |s| value = eval s.to_s, bnd puts "#{s} = #{value.inspect}" end end def test a = 1 s = "hello" var_dump :s, :a end test