ruby picture

RCR 196: Add trace_func accessor to ruby

Submitted by Paul Brannan (Sun Jan 18 02:01:27 UTC 2004)

Abstract

A trace_func method should be added to Ruby that can retrieve the current trace_func.

Problem

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 .

Proposal

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>

  

Analysis

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:

Implementation

ruby picture
Comments Current voting

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.


Strongly opposed 0
Opposed 1
Neutral 1
In favor 3
Strongly advocate 3
ruby picture
If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .