Issue #6895 has been updated by trans (Thomas Sawyer).


>  I understand your proposal.  I use "Thread.new (Thread.start)" analogy
>  (and current set_trace_func analogy).  I think two different behavior is
>  not good.  Which one do you like?

Hmm... Well if we can only have one it would have to be the first b/c it gives most flexibility. But I don't understand why we can't have both when the second (TracePoint.trace) would just be a convenience shortcut to the first, i.e.

  def TracePoint.trace(*events, &block)
    TracePoint.new(*events, &block).trace
  end

>  > Also, I assume that if no events are given as arguments, it includes all events?
>  Yes.
>  
>  >> `eventN' parameter for TracePoint.trace() is set of symbols.  You can specify events what you want to trace.  If you don't specify any events on it, then all events are activate (similar to set_trace_func).
>  
>  But there is an issue.  Now "all" means same events that set_trace_func
>  supports.  But if I add other events like "block invoke", then what mean
>  the "all"?

"All" should mean all. If you add other events then those should be included too. Why would you think not to include your new events?

----------------------------------------
Feature #6895: TracePoint API
https://bugs.ruby-lang.org/issues/6895#change-28978

Author: ko1 (Koichi Sasada)
Status: Closed
Priority: Normal
Assignee: 
Category: 
Target version: 


=begin
= Abstract

Let's introduce TracePoint API that can be replaced with set_trace_func().

= Background

See discussions on [Feature #6649] <http://bugs.ruby-lang.org/issues/show/6649>.

Problems of set_trace_func:

* Invoke trace funcs on all events (C level API can filter events)
* With this spec, we can't add new trace event (compatibility issue)
* Slow because it generates binding object each trace func

= Porposal

Introduce TracePoint API.
  
  trace = TracePoint.trace(event1, event2, ...) do |tp|
    # tp has methods like:
    #   event: event name represented by Symbol like :line.
    #          "c-call", "c-return" is :c_call, :c_return (sub('-', '_'))
    #   file, line: return filename and line number
    #   klass, id: return class or id (depends on a context. Same as set_trace_func)
    #   binding: return (generated) binding object
    #   self: new method.  same as tp.binding.eval('self')
    ... # trace func
    # tp is TracePoint object.
    # In fact, tp is same object as `trace'.
    # We don't need any object creation on trace func.
  end
  ... # Proc are called
  trace.untrace # stop tracing
  ...
  trace.retrace # restart tracing

`eventN' parameter for TracePoint.trace() is set of symbols.  You can specify events what you want to trace.  If you don't specify any events on it, then all events are activate (similar to set_trace_func).

= Implementation

See <https://github.com/ko1/ruby/compare/tracepoint>.

Try <https://github.com/ko1/ruby/tracepoint>.

= Evaluation

TracePoint API doesn't make temporary object on default.  It is faster than current set_trace_func.

  require 'benchmark'
  MAX = 1_000_000
  $c1 = $c2 = 0
  
  Benchmark.bm{|x|
    x.report{
      set_trace_func(lambda{|*args| $c1+=1})
      MAX.times{
        a = 1
      }
      set_trace_func(nil)
    }
    x.report{
      trace = TracePoint.trace(*%i{line call return c_call c_return}){|tp| $c2+=1}
      MAX.times{
        a = 1
      }
      trace.untrace
    }
    x.report{
      trace = TracePoint.trace(*%i{line call return c_call c_return}){|tp| $c2+=1; tp.event; tp.klass; tp.id}
      MAX.times{
        a = 1
      }
      trace.untrace
    }
    x.report{
      trace = TracePoint.trace(*%i{line call return c_call c_return}){|tp| $c2+=1; tp.event; tp.klass; tp.id; tp.binding}
      MAX.times{
        a = 1
      }
      trace.untrace
    }
  }
  __END__
  #=>
         user     system      total        real
   1.600000   0.000000   1.600000 (  1.601750)
   0.280000   0.000000   0.280000 (  0.287466)
   0.750000   0.000000   0.750000 (  0.741344)
   1.400000   0.020000   1.420000 (  1.420574)

= Problems

* TracePoint.trace(...) is good interface?
* Now, noway to specify Thread specific hooks (like Thread#set_trace_func)

= Next Step

I also want to introduce block enter/leave events on TracePoint.

=end




-- 
http://bugs.ruby-lang.org/