Skip to content

Instantly share code, notes, and snippets.

@rocky
Created February 14, 2011 02:16
Show Gist options
  • Save rocky/825393 to your computer and use it in GitHub Desktop.
Save rocky/825393 to your computer and use it in GitHub Desktop.
Save text of methods defined inside IRB with the same line numbers as would be reported in a traceback. ThreadFrame version
require 'irb'
require 'trace'
include Trace
CLASSES = {}
METHODS = {}
MODULES = {}
CHECK_METHODS = %w(define_method method_added singleton_method_added CLASS)
def capture_hook(event, frame, arg=nil)
return unless CHECK_METHODS.member?(frame.method)
klass = eval('self.to_s', frame.binding)
lines = $irb_stmts.split(/\n/)
return unless frame.source_container[0] == 'string' &&
lines.size + $irb_firstline >= frame.source_location[0]
loc = frame.source_location[0]
first_line = lines[loc - $irb_firstline]
puts "checking #{first_line}..." if $IRBHACK_DEBUG
if 'class' == event
if first_line =~ /^\s*class\s+(\S+)/
puts "adding #{klass}" if $IRBHACK_DEBUG
CLASSES[klass] = $irb_stmts
return
end
elsif first_line =~ /^\s*def\s+([^(; \t\n]+)(:?[ \t\n(;])?/
puts "adding #{klass}::#{$1}" if $IRBHACK_DEBUG
METHODS["#{klass}::#{$1}"] = $irb_stmts
end
MODULES[$1] = $irb_stmts if $irb_stmts =~ /^\s*module\s+(\S+)\s+/
end
# Monkeypatch to save the current IRB statement to be run.
# Possibly not needed.
class IRB::Context
alias original_evaluate evaluate
def evaluate(line, line_no)
$irb_stmts = line
$irb_firstline = line_no
original_evaluate(line, line_no)
end
end
workspace = IRB::WorkSpace.new(binding)
irb = IRB::Irb.new(workspace)
trace_filter = Trace::Filter.new
trace_filter.add_trace_func(method(:capture_hook).to_proc,
C_CALL_EVENT_MASK | CLASS_EVENT_MASK)
irb.eval_input
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment