--------------080303090405040506020701 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Michael Neumann wrote: > Hi, Moin! > Is there a way to get the binding of the caller? Yup, there is. See the attached file. It's a bit obscure, but it works and shouldn't be too slow. > Regards, > Michael More regards, Florian Gross --------------080303090405040506020701 Content-Type: text/plain; nameinding_of_caller.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filenameinding_of_caller.rb" begin require 'simplecc' rescue LoadError def Continuation.create(*args, &block) cc il; result allcc {|c| cc ; block.call(cc) if block and args.empty?} result || rgs return *[cc, *result] end end # This method returns the binding of the method that called your # method. It will raise an Exception when you're not inside a method. # # It's used like this: # def inc_counter # Binding.of_caller do |binding| # eval("counter + ", binding) # end # end # counter # 2.times { inc_counter } # counter # 2 # # You will have to put the whole rest of your method into the # block that you pass into this method. If you don't do this # an Exception will be raised. Because of the way that this is # implemented it has to be done this way. If you don't do it # like this it will raise an Exception. def Binding.of_caller(&block) old_critical hread.critical Thread.critical rue count cc, result, error ontinuation.create(nil, nil) error.call if error tracer ambda do |*args| type, context rgs[0], args[4] if type "return" count + # First this method and then calling one will return -- # the trace event of the second event gets the context # of the method which called the method that called this # method. if count 2 # It would be nice if we could restore the trace_func # that was set before we swapped in our own one, but # this is impossible without overloading set_trace_func # in current Ruby. set_trace_func(nil) cc.call(eval("binding", context), nil) end elsif type ! line" set_trace_func(nil) error_msg Binding.of_caller used in non-method context or " + "trailing statements of method using it aren't in the block." cc.call(nil, lambda { raise(ArgumentError, error_msg ) }) end end unless result set_trace_func(tracer) return nil else Thread.critical ld_critical yield result end end --------------080303090405040506020701--