On Mon, 22 Oct 2001, Paul Brannan wrote:

> 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.
> 
Many things are dangerous but still tempting... ;-)

> > 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).
> 
Yes, and I have to fix many of my older programs because of the
Time.times/Process.times issue and I was the one proposing the change!
I think its better to deprecate (but then again I didn't like the
name; IMHO, Binding#call_stack is better).

> 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
> 
Well it won't handle c-calls/returns but that's easily fixed. I
don't remember if there are other gotcha's (I tend to stay away from trace
funcs because of the overhead; you can even do profiling with AspectR and
similar techniques).

Regards,

Robert