From: Paul Brannan Date: 2001-10-22T23:14:11+09:00 Subject: [ruby-talk:22963] Re: stack_frames patch On Mon, 22 Oct 2001, Robert Feldt wrote: > Yes, this is a better approach than previous proposals and IMHO the > "right" way to do it. It certainly looks cleaner, but to get the binding n levels up looks to be O(n)? Generally speaking, I only want the immediate caller's binding anyway, so this isn't too big a deal. One disadvantage of both proposals is that having access to the caller's binding can be VERY dangerous. But it is already possible to use a hack to get the caller's binding (as I show below, and as matju has shown in [ruby-talk:12401], so perhaps a non-hack is a good idea. Perhaps it would be nice if it were possible to get "read-only access" to the caller's binding? > Maybe we should an argument to Binding#caller that will traverse the > bindings until 0 (either returning them all or just the "last" one). But, > of course, its trivial with the current proposal. > > If its accepted Kernel.caller should probably be deprecated... Or perhaps implemented in terms of the proposed methods. There's a lot of code that depends on caller. I think I lean toward deprecating it, because code that uses caller() probably does many evil things (such as parsing the caller string by hand). In the meantime, I use the following in my code. I'm not sure if it works in 100% of cases; would anyone care to comment? (Yes, I know it slows down execution). $call_stack = [] set_trace_func(proc {|*args| case args[0] when 'call' $call_stack.unshift($current_call) when 'return' # If we get an exception, we should still get the normal sequence of # "return" messages. $call_stack.shift() end $current_call = args }) def foo; eval("x = 42", $call_stack[1][4]); end def bar; foo; end x = nil bar puts x # this should display 42 Paul