class DEBUGGER__::Tracer
def colorize(str, color)
def colorize(str, color) # don't colorize trace sent into a file if @into str else super end end
def description
def description nil end
def disable
def disable @tracer.disable end
def enable
def enable @tracer.enable end
def enabled?
def enabled? @tracer.enabled? end
def header depth
def header depth "DEBUGGER (trace/#{@type}) \#th:#{Thread.current.instance_variable_get(:@__thread_client_id)} \#depth:#{'%-2d'%depth}" end
def initialize ui, pattern: nil, into: nil
def initialize ui, pattern: nil, into: nil if /\ADEBUGGER__::(([A-Z][a-z]+?)[A-Z][a-z]+)/ =~ self.class.name @name = $1 @type = $2.downcase end setup if pattern @pattern = Regexp.compile(pattern) else @pattern = nil end if @into = into @output = File.open(into, 'w') @output.puts "PID:#{Process.pid} #{self}" else @output = ui end @key = [@type, @pattern, @into].freeze enable end
def minfo tp
def minfo tp return "block{}" if tp.event == :b_call klass = tp.defined_class if klass.singleton_class? "#{tp.self}.#{tp.method_id}" else "#{klass}\##{tp.method_id}" end end
def out tp, msg = nil, depth = caller.size - 1
def out tp, msg = nil, depth = caller.size - 1 location_str = colorize("#{FrameInfo.pretty_path(tp.path)}:#{tp.lineno}", [:GREEN]) buff = "#{header(depth)}#{msg} at #{location_str}" if false # TODO: Ractor.main? ThreadClient.current.on_trace self.object_id, buff else @output.puts buff @output.flush end end
def skip? tp
def skip? tp ThreadClient.current.management? || skip_path?(tp.path) || skip_with_pattern?(tp) end
def skip_with_pattern?(tp)
def skip_with_pattern?(tp) @pattern && !tp.path.match?(@pattern) end
def to_s
def to_s s = "#{@name}#{description} (#{@tracer.enabled? ? 'enabled' : 'disabled'})" s += " with pattern #{@pattern.inspect}" if @pattern s += " into: #{@into}" if @into s end