ruby_tracer 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -1
- data/README.md +50 -13
- data/lib/ruby_tracer/call_tracer.rb +2 -2
- data/lib/ruby_tracer/irb.rb +90 -0
- data/lib/ruby_tracer/version.rb +1 -1
- data/lib/ruby_tracer.rb +2 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fef5a75aac4be127aabba8e7877625e8b280cb7ff097fbd52c3618fd3cc306ca
|
4
|
+
data.tar.gz: 032abd529d45d4120d9dfb1526bca3cfeef88b220dff618d5d1bcd7e238ef293
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32e1d215a731c211e90690eefa83336237c7bd46587f6fc1dccbf596493917d7f0b60a2d25dca8e3ff22f06ac37e09d862f6dd69222c027187760974b1852a42
|
7
|
+
data.tar.gz: cfbb9f4723666c2fbf57ef1d4e7e41597c1b9024ad279f1b7983be604912623fc52597df103aae7e5bf43da469e2a19466551ce33828245f0036baabd7371378
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby_tracer (0.
|
4
|
+
ruby_tracer (0.3.1)
|
5
|
+
irb (>= 1.6)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
8
9
|
specs:
|
10
|
+
io-console (0.6.0)
|
11
|
+
irb (1.6.2)
|
12
|
+
reline (>= 0.3.0)
|
9
13
|
language_server-protocol (3.17.0.3)
|
10
14
|
power_assert (2.0.2)
|
11
15
|
prettier_print (1.2.0)
|
12
16
|
rake (13.0.6)
|
17
|
+
reline (0.3.2)
|
18
|
+
io-console (~> 0.5)
|
13
19
|
ruby-lsp (0.3.8)
|
14
20
|
language_server-protocol (~> 3.17.0)
|
15
21
|
sorbet-runtime
|
@@ -25,6 +31,7 @@ PLATFORMS
|
|
25
31
|
x86_64-linux
|
26
32
|
|
27
33
|
DEPENDENCIES
|
34
|
+
irb
|
28
35
|
rake (~> 13.0)
|
29
36
|
ruby-lsp
|
30
37
|
ruby_tracer!
|
data/README.md
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
# ruby_tracer
|
2
2
|
|
3
|
-
ruby_tracer is an extraction of [`ruby/debug`](https://github.com/ruby/debug)'s [powerful tracers](https://github.com/ruby/debug/blob/master/lib/debug/tracer.rb), with user-facing APIs and
|
4
|
-
|
5
|
-
Its goal is to help users understand their Ruby programss activities by emitting useful trace information, such us:
|
6
|
-
|
7
|
-
- How and where is the target object is being used (`ObjectTracer`)
|
8
|
-
- What exceptions are raised during the execution (`ExceptionTracer`)
|
9
|
-
- When method calls are being performed (`CallTracer`)
|
10
|
-
- Line execution (`LineTracer`)
|
11
|
-
|
3
|
+
ruby_tracer is an extraction of [`ruby/debug`](https://github.com/ruby/debug)'s [powerful tracers](https://github.com/ruby/debug/blob/master/lib/debug/tracer.rb), with user-facing APIs, IRB-integration, and improvements on accuracy.
|
12
4
|
|
13
5
|
## Installation
|
14
6
|
|
@@ -62,9 +54,54 @@ trace_call { ... } # trace method calls in the given block
|
|
62
54
|
trace_exception { ... } # trace exceptions in the given block
|
63
55
|
```
|
64
56
|
|
57
|
+
### IRB-integration
|
58
|
+
|
59
|
+
Once required, `ruby_tracer` registers a few IRB commands to help you trace Ruby expressions:
|
60
|
+
|
61
|
+
```
|
62
|
+
trace Trace the target object (or self) in the given expression. Usage: `trace [target,] <expression>`
|
63
|
+
trace_call Trace method calls in the given expression. Usage: `trace_call <expression>`
|
64
|
+
trace_exception Trace exceptions in the given expression. Usage: `trace_exception <expression>`
|
65
|
+
```
|
66
|
+
|
67
|
+
**Example**
|
68
|
+
|
69
|
+
```rb
|
70
|
+
# test.rb
|
71
|
+
require "ruby_tracer"
|
72
|
+
|
73
|
+
obj = Object.new
|
74
|
+
|
75
|
+
def obj.foo
|
76
|
+
100
|
77
|
+
end
|
78
|
+
|
79
|
+
def bar(obj)
|
80
|
+
obj.foo
|
81
|
+
end
|
82
|
+
|
83
|
+
binding.irb
|
84
|
+
```
|
85
|
+
|
86
|
+
|
87
|
+
```
|
88
|
+
irb(main):001:0> trace obj, bar(obj)
|
89
|
+
#depth:23 #<Object:0x0000000107a86648> is used as a parameter obj of Object#bar at (eval):1:in `<main>'
|
90
|
+
#depth:24 #<Object:0x0000000107a86648> receives .foo at test.rb:10:in `bar'
|
91
|
+
=> 100
|
92
|
+
irb(main):002:0> trace_call bar(obj)
|
93
|
+
#depth:23> Object#bar at (eval):1:in `<main>'
|
94
|
+
#depth:24> #<Object:0x0000000107a86648>.foo at test.rb:10:in `bar'
|
95
|
+
#depth:24< #<Object:0x0000000107a86648>.foo #=> 100 at test.rb:10:in `bar'
|
96
|
+
#depth:23< Object#bar #=> 100 at (eval):1:in `<main>'
|
97
|
+
=> 100
|
98
|
+
```
|
99
|
+
|
100
|
+
### Tracer Classes
|
101
|
+
|
65
102
|
If you want to have more control over individual traces, you can use individual tracer classes:
|
66
103
|
|
67
|
-
|
104
|
+
#### ObjectTracer
|
68
105
|
|
69
106
|
```rb
|
70
107
|
class User
|
@@ -89,7 +126,7 @@ end
|
|
89
126
|
#depth:4 #<User:0x000000010696cad8 @name="John"> receives #name (User#name) at test.rb:8:in `authorized?'
|
90
127
|
```
|
91
128
|
|
92
|
-
|
129
|
+
#### ExceptionTracer
|
93
130
|
|
94
131
|
```rb
|
95
132
|
ExceptionTracer.new.start
|
@@ -103,7 +140,7 @@ end
|
|
103
140
|
#depth:1 #<RuntimeError: boom> at test.rb:4
|
104
141
|
```
|
105
142
|
|
106
|
-
|
143
|
+
#### CallTracer
|
107
144
|
|
108
145
|
```rb
|
109
146
|
class User
|
@@ -135,7 +172,7 @@ end
|
|
135
172
|
#depth:4 < block #=> true at test.rb:16
|
136
173
|
```
|
137
174
|
|
138
|
-
|
175
|
+
#### LineTracer
|
139
176
|
|
140
177
|
```rb
|
141
178
|
class User
|
@@ -7,8 +7,8 @@ class CallTracer < Tracer::Base
|
|
7
7
|
TracePoint.new(:a_call, :a_return) do |tp|
|
8
8
|
next if skip?(tp)
|
9
9
|
|
10
|
-
location = caller_locations(2, 1).first
|
11
|
-
next if location.
|
10
|
+
location = caller_locations(2, 1).first.to_s
|
11
|
+
next if location.match?(DIR) || location.match?(/<internal:/)
|
12
12
|
|
13
13
|
depth = caller.size
|
14
14
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require "irb/cmd/nop"
|
2
|
+
require "irb"
|
3
|
+
|
4
|
+
module Tracer
|
5
|
+
def self.register_irb_commands
|
6
|
+
ec = IRB::ExtendCommandBundle.instance_variable_get(:@EXTEND_COMMANDS)
|
7
|
+
|
8
|
+
[
|
9
|
+
[:trace, :Trace, nil, [:trace, IRB::ExtendCommandBundle::OVERRIDE_ALL]],
|
10
|
+
[
|
11
|
+
:trace_call,
|
12
|
+
:TraceCall,
|
13
|
+
nil,
|
14
|
+
[:trace_call, IRB::ExtendCommandBundle::OVERRIDE_ALL]
|
15
|
+
],
|
16
|
+
[
|
17
|
+
:trace_exception,
|
18
|
+
:TraceException,
|
19
|
+
nil,
|
20
|
+
[:trace_exception, IRB::ExtendCommandBundle::OVERRIDE_ALL]
|
21
|
+
]
|
22
|
+
].each do |ecconfig|
|
23
|
+
ec.push(ecconfig)
|
24
|
+
IRB::ExtendCommandBundle.def_extend_command(*ecconfig)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module IRB
|
30
|
+
module ExtendCommand
|
31
|
+
class TraceCommand < Nop
|
32
|
+
class << self
|
33
|
+
def transform_args(args)
|
34
|
+
# Return a string literal as is for backward compatibility
|
35
|
+
if args.empty? || string_literal?(args)
|
36
|
+
args
|
37
|
+
else # Otherwise, consider the input as a String for convenience
|
38
|
+
args.strip.dump
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Trace < TraceCommand
|
45
|
+
category "Tracing"
|
46
|
+
description "Trace the target object (or self) in the given expression. Usage: `trace [target,] <expression>`"
|
47
|
+
|
48
|
+
def execute(*args)
|
49
|
+
args = args.first.split(/,/, 2)
|
50
|
+
|
51
|
+
case args.size
|
52
|
+
when 1
|
53
|
+
target = irb_context.workspace.main
|
54
|
+
expression = args.first
|
55
|
+
when 2
|
56
|
+
target = eval(args.first, irb_context.workspace.binding)
|
57
|
+
expression = args.last
|
58
|
+
else
|
59
|
+
raise ArgumentError,
|
60
|
+
"wrong number of arguments (given #{args.size}, expected 1..2)"
|
61
|
+
end
|
62
|
+
|
63
|
+
b = irb_context.workspace.binding
|
64
|
+
Tracer.trace(target) { eval(expression, b) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class TraceCall < TraceCommand
|
69
|
+
category "Tracing"
|
70
|
+
description "Trace method calls in the given expression. Usage: `trace_call <expression>`"
|
71
|
+
|
72
|
+
def execute(expression)
|
73
|
+
b = irb_context.workspace.binding
|
74
|
+
Tracer.trace_call { eval(expression, b) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class TraceException < TraceCommand
|
79
|
+
category "Tracing"
|
80
|
+
description "Trace exceptions in the given expression. Usage: `trace_exception <expression>`"
|
81
|
+
|
82
|
+
def execute(expression)
|
83
|
+
b = irb_context.workspace.binding
|
84
|
+
Tracer.trace_exception { eval(expression, b) }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Tracer.register_irb_commands
|
data/lib/ruby_tracer/version.rb
CHANGED
data/lib/ruby_tracer.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_tracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stan Lo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
12
|
-
dependencies:
|
11
|
+
date: 2023-02-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: irb
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
13
27
|
description: A Ruby tracer
|
14
28
|
email:
|
15
29
|
- stan001212@gmail.com
|
@@ -30,6 +44,7 @@ files:
|
|
30
44
|
- lib/ruby_tracer/color.rb
|
31
45
|
- lib/ruby_tracer/exception_tracer.rb
|
32
46
|
- lib/ruby_tracer/helper.rb
|
47
|
+
- lib/ruby_tracer/irb.rb
|
33
48
|
- lib/ruby_tracer/line_tracer.rb
|
34
49
|
- lib/ruby_tracer/object_tracer.rb
|
35
50
|
- lib/ruby_tracer/version.rb
|