Submitted by Paul Brannan (Sun Jan 18 02:01:27 UTC 2004)
It is currently only possible to have one trace_func per Ruby process. If there were an accessor to retrieve the current trace_func, then it would be possible to chain trace_funcs. This would be useful because it would allow applications that use trace_funcs to be profiled (it's currently not possible, because the profiler changes the trace_func).
Nathaniel Talbott described in why he wanted this feature, and Robert Feldt proposed a similar solution in .
There should be a global function trace_func() added to Ruby that returns the current trace_func.
The profiler and the tracer should be modified to call the old trace_func.
Example:
set_trace_func proc { |*x| } # trace_func 1
old_trace_func = trace_func() set_trace_func proc { |*x| old_trace_func.call(*x) } # trace_func 2</pre>
This solution allows trace_funcs to be chained, so that there can be more than one trace_func in a Ruby process. Otherwise, it is not possible to profile an application that uses trace funcs.
One alternate solution is to change set_trace_func to return the old trace_func. However, set_trace_func currently returns the new trace_func, so this would introduce a backward incompatibility.
Another alternate solution would be to change set_trace_func to add an additional trace_func instead of replacing the old one (Ruby would internally keep a list of trace funcs and call them in the order they were added). The global function remove_trace_func could be used to remove the trace_func. This is the approach taken in RubyTreasures, because it doesn't require changes to code that uses set_trace_func:
Comments | Current voting | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
I am against the idea, because chaining is ugly. It's error prone, and strongly couples all trace functions. If you really want to set multiple trace functions at the same time, I think, you need to design new trace function API, and provide set_trace_func as compatibility API implemented using new API.
I'm not sure yet whether we need multiple trace functions though.
- matz.
You bring up a good point about the ugliness of chaining. It doesn't allow a trace func to easily be removed from the chain. While I think that this is a minor limitation (since I don't think that removing trace funcs in any order other than the reverse order in which they were added is very common), if we have support for multiple trace_funcs, it would be better to have an API that covers both the common uses and the less common uses.
I would prefer to see a method to add a trace func and a method to remove a trace func (similar what I have in RubyTreasures). This is a little more involved to implement than the RCR I proposed.
As for whether there is a need for this feature, I have to be honest. If you had asked me two years ago if Ruby needs this, I would have said yes, absolutely. I've gotten by without it for two years though, by replacing set_trace_func with my own version when necessary, and by writing code that doesn't use set_trace_func. I'm not 100% convinced that Ruby "needs" this feature, but it does seem odd to me that I can set a trace func, I can unset a trace func, but I can't query the current trace func (esp. considering this is just a few lines of C).
-- Paul Brannan
Ruby could use some improvement in this area, but I think more importantly Ruby should expand its hook methods. If done properly these could cover most, if not all, use cases of the trace function --and be more robust a solution.