class DEBUGGER__::ThreadClient::Recorder
def append frames
def append frames @log << frames end
def can_step_back?
def can_step_back? log.size > @index end
def current_frame
def current_frame if @index == 0 f = @backup_frames @backup_frames = nil f else frames = @log[log_index] frames end end
def current_position
def current_position puts "INDEX: #{@index}" li = log_index @log.each_with_index{|frame, i| loc = frame.first&.location prefix = i == li ? "=> " : ' ' puts "#{prefix} #{loc}" } end
def disable
def disable if @tp_recorder.enabled? @log.clear @tp_recorder.disable end end
def enable
def enable unless @tp_recorder.enabled? @log.clear @tp_recorder.enable end end
def enabled?
def enabled? @tp_recorder.enabled? end
def initialize
def initialize @log = [] @index = 0 @backup_frames = nil thread = Thread.current @tp_recorder ||= TracePoint.new(:line){|tp| next unless Thread.current == thread # can't be replaced by skip_location next if skip_internal_path?(tp.path) loc = caller_locations(1, 1).first next if skip_location?(loc) frames = DEBUGGER__.capture_frames(__dir__) frames.each{|frame| if b = frame.binding frame.binding = nil frame._local_variables = b.local_variables.map{|name| [name, b.local_variable_get(name)] }.to_h frame._callee = b.eval('__callee__') end } append(frames) } end
def log_index
def log_index @log.size - @index end
def replaying?
def replaying? @index > 0 end
def step_back iter
def step_back iter @index += iter if @index > @log.size @index = @log.size end end
def step_forward iter
def step_forward iter @index -= iter if @index < 0 @index = 0 end end
def step_reset
def step_reset @index = 0 @backup_frames = nil end