class Trip
Constants
- END_STATE
@private
- Error
- InProgressError
- InternalError
- PAUSE_WHEN
@private
- PauseError
- RESCUABLE_EXCEPTIONS
@private
- RUN_STATE
@private
- SLEEP_STATE
@private
- VERSION
Public Class Methods
analyze(io: $stdout, color: true, page: false, precision: Trip::Analyzer::DEFAULT_PRECISION, &blk)
click to toggle source
Analyzes a block of Ruby code by printing a detailed trace to $stdout.
@example
# Prints trace to $stdout (no paging) Trip.analyze { ERB.new("").result } # Prints trace with a pager (less) Trip.analyze(page: true) { ERB.new("").result } # Prints a trace to a StringIO with colors disabled # and then returns the io. io = Trip.analyze(color: false, io: StringIO.new) io.string
@param (see Trip::Analyzer#analyze
)
@return [void]
# File lib/trip/analyzer.rb, line 129 def Trip.analyze io: $stdout, color: true, page: false, precision: Trip::Analyzer::DEFAULT_PRECISION, &blk Trip::Analyzer.new(&blk).analyze( io: io, color: color, page: page, precision: precision ) end
new(&block)
click to toggle source
@param [Proc] block
The block to be traced.
@return [Trip]
Returns an instance of Trip.
# File lib/trip.rb, line 37 def initialize(&block) raise ArgumentError, "Expected a block to trace" unless block @thread = nil @block = block @queue = nil @pause_when = PAUSE_WHEN @caller = Thread.current end
Public Instance Methods
finished?()
click to toggle source
@return [Boolean]
Returns true when the tracer thread has finished.
# File lib/trip.rb, line 88 def finished? @thread and END_STATE.include?(@thread.status) end
pause_when(callable = nil, &block)
click to toggle source
Stores a callable that decides when to pause the tracer.
@param [Proc] callable
A block or an object that responds to "#call".
@raise [ArgumentError]
Raised when the "callable" argument is not provided.
@return [nil]
Returns nil.
@example
trip = Trip.new { Kernel.puts 1+1 } trip.pause_when {|event| event.c_call? || event.c_return? } event = trip.start
# File lib/trip.rb, line 61 def pause_when(callable = nil, &block) pauser = callable || block raise ArgumentError, "Expected a block or an object implementing #call" unless pauser @pause_when = pauser nil end
resume()
click to toggle source
Resumes a trace or starts one if {#start} hasn't been called.
@raise [Trip::PauseError] (see start
)
@raise [Trip::InternalError] (see start
)
@return [Trip::Event, nil]
Returns an event or nil.
# File lib/trip.rb, line 130 def resume return start unless started? if sleeping? @thread.wakeup @queue.deq end end
running?()
click to toggle source
@return [Boolean]
Returns true when the tracer thread is running.
# File lib/trip.rb, line 76 def running? @thread and @thread.status == RUN_STATE end
sleeping?()
click to toggle source
@return [Boolean]
Returns true when the tracer thread is sleeping.
# File lib/trip.rb, line 82 def sleeping? @thread and @thread.status == SLEEP_STATE end
start()
click to toggle source
Starts the tracer.
@raise [Trip::InProgessError]
Raised when there is already a trace in progress.
@raise [Trip::PauseError]
Raised when an exception is raised by the callable given to {#pause_when}.
@raise [Trip::InternalError]
Raised when an exception internal to Trip is raised.
@return [Trip::Event, nil]
Returns an event, or nil
# File lib/trip.rb, line 106 def start if started? && !finished? raise InProgressError, "A trace is already in progress." \ "Call #resume instead ?" end @queue = Queue.new @thread = Thread.new do Thread.current.set_trace_func method(:on_event).to_proc @block.call Thread.current.set_trace_func(nil) @queue.enq(nil) end @queue.deq end
started?()
click to toggle source
@return [Boolean]
Returns true when a trace has been started
# File lib/trip.rb, line 70 def started? @thread != nil end
stop()
click to toggle source
Stops the tracer.
@return [nil]
# File lib/trip.rb, line 141 def stop if @thread @thread.set_trace_func(nil) @thread.exit @thread.join nil end end
Private Instance Methods
on_event(name, path, lineno, method_name, binding, mod)
click to toggle source
# File lib/trip.rb, line 152 def on_event(name, path, lineno, method_name, binding, mod) internal_error = Trip::InternalError.new("The tracer encountered an internal error and crashed") pause_error = Trip::PauseError.new("The pause Proc encountered an error and crashed") rescued_run(internal_error) do event = Event.new name, { path: path, lineno: lineno, module: mod, method_name: method_name, binding: binding } return if event.path == __FILE__ if rescued_run(pause_error) { @pause_when.call(event) } @queue.enq(event) Thread.stop end end end
rescued_run(e) { || ... }
click to toggle source
# File lib/trip.rb, line 171 def rescued_run(e) yield rescue *RESCUABLE_EXCEPTIONS => cause e.define_singleton_method(:cause) { cause } Thread.current.set_trace_func(nil) @caller.raise(e) false end