Class: Tracer::Base

Inherits:
Object
  • Object
show all
Includes:
Color
Defined in:
lib/tracer/base.rb

Defined Under Namespace

Classes: LimitedPP

Constant Summary collapse

DIR =
__dir__
M_OBJECT_ID =
Object.instance_method(:object_id)
M_INSPECT =
Object.instance_method(:inspect)
M_CLASS =
Object.instance_method(:class)
M_IS_A =
Object.instance_method(:is_a?)
M_INSTANCE_VARIABLE_GET =
Object.instance_method(:instance_variable_get)
HOME =
ENV["HOME"] ? (ENV["HOME"] + "/") : nil

Constants included from Color

Color::BLUE, Color::BOLD, Color::CLEAR, Color::CYAN, Color::GREEN, Color::MAGENTA, Color::RED, Color::REVERSE, Color::UNDERLINE, Color::YELLOW

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Color

clear, colorize, #colorize, #colorize_blue, #colorize_cyan, #colorize_magenta

Constructor Details

#initialize(output: STDOUT, pattern: nil, colorize: nil, depth_offset: 0, header: nil) ⇒ Base

Returns a new instance of Base.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/tracer/base.rb', line 76

def initialize(
  output: STDOUT,
  pattern: nil,
  colorize: nil,
  depth_offset: 0,
  header: nil
)
  @name = self.class.name
  @type = @name.sub(/Tracer\z/, "")
  @output = output
  @depth_offset = depth_offset
  @colorize = colorize || colorizable?
  @header = header

  if pattern
    @pattern = Regexp.compile(pattern)
  else
    @pattern = nil
  end

  @tp = setup_tp
end

Instance Attribute Details

#headerObject (readonly)

Returns the value of attribute header.



74
75
76
# File 'lib/tracer/base.rb', line 74

def header
  @header
end

Instance Method Details

#colorizable?Boolean

Returns:

  • (Boolean)


177
178
179
180
# File 'lib/tracer/base.rb', line 177

def colorizable?
  no_color = (nc = ENV["NO_COLOR"]).nil? || nc.empty?
  @output.is_a?(IO) && @output.tty? && no_color
end

#descriptionObject



109
110
111
# File 'lib/tracer/base.rb', line 109

def description
  "(#{@tp.enabled? ? "enabled" : "disabled"})"
end

#keyObject



99
100
101
# File 'lib/tracer/base.rb', line 99

def key
  [@type, @pattern, @into].freeze
end

#minfo(tp) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/tracer/base.rb', line 165

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

#out(tp, msg = nil, depth: caller.size - 1, location: nil) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
# File 'lib/tracer/base.rb', line 148

def out(tp, msg = nil, depth: caller.size - 1, location: nil)
  location ||= "#{tp.path}:#{tp.lineno}"
  if header
    str = +"#{header} "
  else
    str = +""
  end
  str << "\#depth:#{"%-2d" % depth}#{msg} at #{colorize("#{location}", [:GREEN])}"

  puts str
end

#pretty_path(path) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/tracer/base.rb', line 59

def pretty_path(path)
  return "#<none>" unless path

  case
  when path.start_with?(dir = RbConfig::CONFIG["rubylibdir"] + "/")
    path.sub(dir, "$(rubylibdir)/")
  when Gem.path.any? { |gp| path.start_with?(dir = gp + "/gems/") }
    path.sub(dir, "$(Gem)/")
  when HOME && path.start_with?(HOME)
    path.sub(HOME, "~/")
  else
    path
  end
end

#puts(msg) ⇒ Object



160
161
162
163
# File 'lib/tracer/base.rb', line 160

def puts(msg)
  @output.puts msg
  @output.flush
end

#safe_inspect(obj, max_length: 40) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/tracer/base.rb', line 45

def safe_inspect(obj, max_length: 40)
  LimitedPP.pp(obj, max_length)
rescue NoMethodError => e
  klass, oid = M_CLASS.bind_call(obj), M_OBJECT_ID.bind_call(obj)
  if obj == (r = e.receiver)
    "#<#{klass.name}#{oid} does not have \#inspect>"
  else
    rklass, roid = M_CLASS.bind_call(r), M_OBJECT_ID.bind_call(r)
    "#<#{klass.name}:#{roid} contains #<#{rklass}:#{roid} and it does not have #inspect>"
  end
rescue Exception => e
  "<#inspect raises #{e.inspect}>"
end

#skip?(tp) ⇒ Boolean

Returns:

  • (Boolean)


136
137
138
# File 'lib/tracer/base.rb', line 136

def skip?(tp)
  skip_internal?(tp) || skip_with_pattern?(tp)
end

#skip_internal?(tp) ⇒ Boolean

Returns:

  • (Boolean)


144
145
146
# File 'lib/tracer/base.rb', line 144

def skip_internal?(tp)
  tp.path.match?(DIR)
end

#skip_with_pattern?(tp) ⇒ Boolean

Returns:

  • (Boolean)


140
141
142
# File 'lib/tracer/base.rb', line 140

def skip_with_pattern?(tp)
  @pattern && !tp.path.match?(@pattern)
end

#start(&block) ⇒ Object



113
114
115
116
117
118
119
120
121
122
# File 'lib/tracer/base.rb', line 113

def start(&block)
  puts "PID:#{Process.pid} #{self}" if @output.is_a?(File)

  if block
    @tp.enable(&block)
  else
    @tp.enable
    self
  end
end

#started?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'lib/tracer/base.rb', line 128

def started?
  @tp.enabled?
end

#stopObject



124
125
126
# File 'lib/tracer/base.rb', line 124

def stop
  @tp.disable
end

#stopped?Boolean

Returns:

  • (Boolean)


132
133
134
# File 'lib/tracer/base.rb', line 132

def stopped?
  !started?
end

#to_sObject



103
104
105
106
107
# File 'lib/tracer/base.rb', line 103

def to_s
  s = "#{@name} #{description}"
  s += " with pattern #{@pattern.inspect}" if @pattern
  s
end