Class: TracePoint

Inherits:
Object
  • Object
show all
Defined in:
lib/tracepoint.rb

Overview

TracePoint

A TracePoint is a Binding with the addition event information. And it’s a better way to use set_trace_func.

A TracePoint is a Binding with the addition of event information. Among other things, it functions very well as the join-point for Event-based AOP.

Usage

TracePoint.trace { |tp|
  puts "#{tp.self.class}\t#{tp.called}\t#{tp.event}\t#{tp.return?}\t#{tp.back == tp.bind}"
}

1 + 1

produces

Class   trace   return     true    false
Object          line       false   false
Fixnum  +       c-call     false   false
Fixnum  +       c-return   false   false

Notes

CodePoint alias for Binding has been deprecated.

We can’t subclass Binding, so we delegate.

Constant Summary collapse

VERSION =

TODO: this is here only b/c of lookup bugs in Ruby 1.8.x.

['version']
EVENT_MAP =

methods for working with events

{
  :all     => ['call', 'c-call', 'return', 'c-return', 'line', 'class', 'end', 'raise'],
  :before  => ['call', 'c-call'],
  :after   => ['return', 'c-return'],
  :call    => ['call'],
  :return  => ['return'],
  :ccall   => ['c-call'],
  :creturn => ['c-return'],
  :line    => ['line'],
  :class   => ['class'],
  :end     => ['end'],
  :raise   => ['raise']
}
@@active =
false
@@index =
{}
@@procs =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(event, file, line, method, bind, back_binding = bind) ⇒ TracePoint

Until Ruby has a built-in way to get the name of the calling method that information must be passed into the TracePoint.



116
117
118
119
120
121
122
123
# File 'lib/tracepoint.rb', line 116

def initialize( event, file, line, method, bind, back_binding=bind )
  @event   = event
  @file    = file
  @line    = line
  @method  = method
  @binding = bind || TOPLEVEL_BINDING #?
  @back_binding = back_binding
end

Instance Attribute Details

#back_bindingObject

– instance ——————-



112
113
114
# File 'lib/tracepoint.rb', line 112

def back_binding
  @back_binding
end

#bindingObject

– instance ——————-



112
113
114
# File 'lib/tracepoint.rb', line 112

def binding
  @binding
end

#eventObject

– instance ——————-



112
113
114
# File 'lib/tracepoint.rb', line 112

def event
  @event
end

#fileObject

– instance ——————-



112
113
114
# File 'lib/tracepoint.rb', line 112

def file
  @file
end

#lineObject

– instance ——————-



112
113
114
# File 'lib/tracepoint.rb', line 112

def line
  @line
end

Class Method Details

.activateObject

Activate tracing.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/tracepoint.rb', line 71

def activate
  @@active = true
  bb_stack = []
  fn = lambda do |e, f, l, m, b, k|
    unless k == TracePoint or (k == Kernel && m == :set_trace_func)
      #(p e, f, l, m, b, k, @@bb_stack; puts "---") if $DEBUG
      if ['call','c-call','class'].include?(e)
        bb_stack << b
      elsif ['return','c-return','end'].include?(e)
        bb = bb_stack.pop
      end
      b = bb if ! b    # this sucks!
      tp = TracePoint.new(e, f, l, m, b, bb)
      @@procs.each{ |fn| fn.call(tp) }
    end
  end
  set_trace_func(fn)
end

.active?Boolean

Is tracing active?

Returns:

  • (Boolean)


66
67
68
# File 'lib/tracepoint.rb', line 66

def active?
  @@active
end

.clear(name = nil) ⇒ Object

Clear all trace procedures, or a specific trace by name.



97
98
99
100
101
102
103
104
105
106
# File 'lib/tracepoint.rb', line 97

def clear(name=nil)
  if name
    raise "Undefined trace -- #{name}" unless @@index.key?(name)
    @@procs.delete(@@index.delete(name))
  else
    deactivate
    @@index = {}
    @@procs = []
  end
end

.const_missing(name) ⇒ Object

Access metadata as constants.



42
43
44
45
# File 'lib/tracepoint.rb', line 42

def self.const_missing(name)
  name = name.to_s.downcase
  [name] || super(name)
end

.deactivateObject

Deactivate tracing.



91
92
93
94
# File 'lib/tracepoint.rb', line 91

def deactivate
  @@active = false
  set_trace_func nil
end

.metadataObject

Access to metadata.



34
35
36
37
38
39
# File 'lib/tracepoint.rb', line 34

def self.
  @metadata ||= (
    require 'yaml'
    YAML.load(File.new(File.dirname(__FILE__) + '/tracepoint.yml'))
  )
end

.trace(name = nil, &procedure) ⇒ Object

Trace execution using a TracePoint.



60
61
62
63
# File 'lib/tracepoint.rb', line 60

def trace(name=nil, &procedure)
  @@index[name] = procedure if name
  @@procs << procedure
end

Instance Method Details

#===(e) ⇒ Object

For use in case conditions



178
179
180
# File 'lib/tracepoint.rb', line 178

def ===(e)
  EVENT_MAP[e].include?(@event)
end

#backObject

Shorthand for #back_binding.



131
132
133
# File 'lib/tracepoint.rb', line 131

def back
  @back_binding
end

#bindObject

Shorthand for #binding.



126
127
128
# File 'lib/tracepoint.rb', line 126

def bind
  @binding
end

#calleeObject Also known as: method_name

Returns the name of the event’s method. – This could delegate to the binding if Ruby had an internal way to retrieve the current method name. ++



146
# File 'lib/tracepoint.rb', line 146

def callee ; @method ; end

#event?Boolean

Is the trace point defined or undefined?

Returns:

  • (Boolean)


174
# File 'lib/tracepoint.rb', line 174

def event? ; !! @event ; end

#event_map(e) ⇒ Object



171
# File 'lib/tracepoint.rb', line 171

def event_map(e) ; EVENT_MAP[e] ; end

#eventless?Boolean

Returns:

  • (Boolean)


175
# File 'lib/tracepoint.rb', line 175

def eventless? ; ! @event ; end

#selfObject

Delegates “self” to the binding which in turn delegates the binding object.



137
138
139
# File 'lib/tracepoint.rb', line 137

def self
  @binding.self #if @binding
end