im-lost 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +51 -53
- data/examples/foo.rb +50 -50
- data/lib/im-lost/version.rb +1 -1
- data/lib/im-lost.rb +141 -126
- metadata +4 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a11bb08b82dde3d4d56939a25d4898c77ef75ce9e82659511f8a47e6b1d0b9d
|
4
|
+
data.tar.gz: 073e42d29b09cd54db36a39d12e334d7cc2a5b9fbd5d2f3447265cd84cc278da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb4ee264f51b598b2b086033958a6eb587934a8d2be08c009f6c6d4c9991b84fd0657b5b691cdde7e50a2fb662316a81b6b38a5d7ada949277c14da99d12021a
|
7
|
+
data.tar.gz: 8b183a0464fb8a64a238792347ae697e557440b3cfc58bb26251f7b23ce2ef7ee766f2ca02fd0382ff449f3c17244c45dbfee494122bd6f28efd97f9e1b80e89
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -10,7 +10,7 @@ ImLost helps you by analyzing function calls of objects, informing you about exc
|
|
10
10
|
|
11
11
|
## Description
|
12
12
|
|
13
|
-
If you like to
|
13
|
+
If you like to understand method call details you get a call trace with `ImLost.trace`:
|
14
14
|
|
15
15
|
```ruby
|
16
16
|
File.open('test.txt', 'w') do |file|
|
@@ -75,8 +75,6 @@ See the [online help](https://rubydoc.info/gems/im-lost/ImLost) for more!
|
|
75
75
|
```ruby
|
76
76
|
require 'im-lost'
|
77
77
|
|
78
|
-
require_relative '../lib/im-lost'
|
79
|
-
|
80
78
|
class Foo
|
81
79
|
def self.create(value:) = new(value)
|
82
80
|
|
@@ -109,56 +107,56 @@ my_foo.foo(3) { puts _1 }
|
|
109
107
|
ImLost.vars(my_foo)
|
110
108
|
|
111
109
|
# output will look like
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
134
|
-
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
110
|
+
# > Foo.create(:foo!)
|
111
|
+
# ./examples/foo.rb:24
|
112
|
+
# > Foo.new(*args)
|
113
|
+
# ./examples/foo.rb:6
|
114
|
+
# < Foo.new(*args)
|
115
|
+
# ./examples/foo.rb:6
|
116
|
+
# = #<Foo:0x0000000104c24b88 @value=:foo!>
|
117
|
+
# < Foo.create(:foo!)
|
118
|
+
# ./examples/foo.rb:24
|
119
|
+
# = #<Foo:0x0000000104c24b88 @value=:foo!>
|
120
|
+
# > Foo#foo(1, *[], :none, **{}, &nil)
|
121
|
+
# ./examples/foo.rb:27
|
122
|
+
# > Foo#bar()
|
123
|
+
# ./examples/foo.rb:15
|
124
|
+
# < Foo#bar()
|
125
|
+
# ./examples/foo.rb:15
|
126
|
+
# = :bar
|
127
|
+
# < Foo#foo(1, *[], :none, **{}, &nil)
|
128
|
+
# ./examples/foo.rb:27
|
129
|
+
# = "1-none-[]-{}-bar"
|
130
|
+
# * ./examples/foo.rb:28
|
131
|
+
# > instance variables
|
132
|
+
# @value: "1-none-[]-{}-bar"
|
133
|
+
# > Foo#foo(2, *[:a, :b, :c], :some, **{name: :value}, &nil)
|
134
|
+
# ./examples/foo.rb:30
|
135
|
+
# > Foo#bar()
|
136
|
+
# ./examples/foo.rb:15
|
137
|
+
# < Foo#bar()
|
138
|
+
# ./examples/foo.rb:15
|
139
|
+
# = :bar
|
140
|
+
# < Foo#foo(2, *[:a, :b, :c], :some, **{name: :value}, &nil)
|
141
|
+
# ./examples/foo.rb:30
|
142
|
+
# = "2-some-[a,b,c]-{name: :value}-bar"
|
143
|
+
# * ./examples/foo.rb:31
|
144
|
+
# > instance variables
|
145
|
+
# @value: "2-some-[a,b,c]-{name: :value}-bar"
|
146
|
+
# > Foo#foo(3, *[], nil, **{}, &#<Proc:0x0000000104c22180 ./examples/foo.rb:33>)
|
147
|
+
# ./examples/foo.rb:33
|
148
|
+
# > Foo#bar()
|
149
|
+
# ./examples/foo.rb:15
|
150
|
+
# < Foo#bar()
|
151
|
+
# ./examples/foo.rb:15
|
152
|
+
# = :bar
|
153
|
+
# 3--[]-{}-bar
|
154
|
+
# < Foo#foo(3, *[], nil, **{}, &#<Proc:0x0000000104c22180 ./examples/foo.rb:33>)
|
155
|
+
# ./examples/foo.rb:33
|
156
|
+
# = nil
|
157
|
+
# * ./examples/foo.rb:34
|
158
|
+
# > instance variables
|
159
|
+
# @value: "3--[]-{}-bar"
|
162
160
|
```
|
163
161
|
|
164
162
|
See [examples dir](./examples) for more…
|
data/examples/foo.rb
CHANGED
@@ -34,53 +34,53 @@ my_foo.foo(3) { puts _1 }
|
|
34
34
|
ImLost.vars(my_foo)
|
35
35
|
|
36
36
|
# output will look like
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
37
|
+
# > Foo.create(:foo!)
|
38
|
+
# ./examples/foo.rb:24
|
39
|
+
# > Foo.new(*args)
|
40
|
+
# ./examples/foo.rb:6
|
41
|
+
# < Foo.new(*args)
|
42
|
+
# ./examples/foo.rb:6
|
43
|
+
# = #<Foo:0x0000000104c24b88 @value=:foo!>
|
44
|
+
# < Foo.create(:foo!)
|
45
|
+
# ./examples/foo.rb:24
|
46
|
+
# = #<Foo:0x0000000104c24b88 @value=:foo!>
|
47
|
+
# > Foo#foo(1, *[], :none, **{}, &nil)
|
48
|
+
# ./examples/foo.rb:27
|
49
|
+
# > Foo#bar()
|
50
|
+
# ./examples/foo.rb:15
|
51
|
+
# < Foo#bar()
|
52
|
+
# ./examples/foo.rb:15
|
53
|
+
# = :bar
|
54
|
+
# < Foo#foo(1, *[], :none, **{}, &nil)
|
55
|
+
# ./examples/foo.rb:27
|
56
|
+
# = "1-none-[]-{}-bar"
|
57
|
+
# * ./examples/foo.rb:28
|
58
|
+
# > instance variables
|
59
|
+
# @value: "1-none-[]-{}-bar"
|
60
|
+
# > Foo#foo(2, *[:a, :b, :c], :some, **{name: :value}, &nil)
|
61
|
+
# ./examples/foo.rb:30
|
62
|
+
# > Foo#bar()
|
63
|
+
# ./examples/foo.rb:15
|
64
|
+
# < Foo#bar()
|
65
|
+
# ./examples/foo.rb:15
|
66
|
+
# = :bar
|
67
|
+
# < Foo#foo(2, *[:a, :b, :c], :some, **{name: :value}, &nil)
|
68
|
+
# ./examples/foo.rb:30
|
69
|
+
# = "2-some-[a,b,c]-{name: :value}-bar"
|
70
|
+
# * ./examples/foo.rb:31
|
71
|
+
# > instance variables
|
72
|
+
# @value: "2-some-[a,b,c]-{name: :value}-bar"
|
73
|
+
# > Foo#foo(3, *[], nil, **{}, &#<Proc:0x0000000104c22180 ./examples/foo.rb:33>)
|
74
|
+
# ./examples/foo.rb:33
|
75
|
+
# > Foo#bar()
|
76
|
+
# ./examples/foo.rb:15
|
77
|
+
# < Foo#bar()
|
78
|
+
# ./examples/foo.rb:15
|
79
|
+
# = :bar
|
80
|
+
# 3--[]-{}-bar
|
81
|
+
# < Foo#foo(3, *[], nil, **{}, &#<Proc:0x0000000104c22180 ./examples/foo.rb:33>)
|
82
|
+
# ./examples/foo.rb:33
|
83
|
+
# = nil
|
84
|
+
# * ./examples/foo.rb:34
|
85
|
+
# > instance variables
|
86
|
+
# @value: "3--[]-{}-bar"
|
data/lib/im-lost/version.rb
CHANGED
data/lib/im-lost.rb
CHANGED
@@ -54,7 +54,7 @@ module ImLost
|
|
54
54
|
return @output = value if defined?(value.<<)
|
55
55
|
raise(
|
56
56
|
NoMethodError,
|
57
|
-
"undefined method
|
57
|
+
"undefined method '#<<' for an instance of #{
|
58
58
|
Kernel.instance_method(:class).bind(value).call
|
59
59
|
}"
|
60
60
|
)
|
@@ -73,18 +73,18 @@ module ImLost
|
|
73
73
|
# @attribute [r] trace_calls
|
74
74
|
# @return [Boolean] whether method calls will be traced
|
75
75
|
#
|
76
|
-
def trace_calls = @trace_calls
|
76
|
+
def trace_calls = @trace_calls.enabled?
|
77
77
|
|
78
78
|
def trace_calls=(value)
|
79
79
|
if value
|
80
|
-
@trace_calls.
|
80
|
+
@trace_calls.enable unless trace_calls
|
81
81
|
elsif trace_calls
|
82
|
-
@trace_calls.
|
82
|
+
@trace_calls.disable
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
86
|
#
|
87
|
-
# Traces
|
87
|
+
# Traces exceptions raised within a given block.
|
88
88
|
#
|
89
89
|
# @example Trace exception and rescue handling
|
90
90
|
# ImLost.trace_exceptions do
|
@@ -101,36 +101,38 @@ module ImLost
|
|
101
101
|
# # x RuntimeError: something went wrong!
|
102
102
|
# # /examples/test.rb:4
|
103
103
|
#
|
104
|
-
# @param with_locations [Boolean]
|
104
|
+
# @param with_locations [Boolean] whether the locations should be included
|
105
105
|
# into the exception trace information
|
106
106
|
# @yieldreturn [Object] return result
|
107
107
|
#
|
108
108
|
def trace_exceptions(with_locations: true)
|
109
109
|
return unless block_given?
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
110
|
+
begin
|
111
|
+
we = @trace_exceptions.enabled?
|
112
|
+
el = @exception_locations
|
113
|
+
@exception_locations = with_locations
|
114
|
+
@trace_exceptions.enable unless we
|
115
|
+
yield
|
116
|
+
ensure
|
117
|
+
@trace_exceptions.disable unless we
|
118
|
+
@exception_locations = el
|
119
|
+
end
|
118
120
|
end
|
119
121
|
|
120
122
|
#
|
121
|
-
# Enables/disables tracing of returned
|
123
|
+
# Enables/disables tracing of returned values of method calls.
|
122
124
|
# This is enabled by default.
|
123
125
|
#
|
124
126
|
# @attribute [r] trace_results
|
125
127
|
# @return [Boolean] whether return values will be traced
|
126
128
|
#
|
127
|
-
def trace_results = @trace_results
|
129
|
+
def trace_results = @trace_results.enabled?
|
128
130
|
|
129
131
|
def trace_results=(value)
|
130
132
|
if value
|
131
|
-
@trace_results.
|
133
|
+
@trace_results.enable unless trace_results
|
132
134
|
elsif trace_results
|
133
|
-
@trace_results.
|
135
|
+
@trace_results.disable
|
134
136
|
end
|
135
137
|
end
|
136
138
|
|
@@ -259,7 +261,7 @@ module ImLost
|
|
259
261
|
#
|
260
262
|
# Inspect internal variables of a given object.
|
261
263
|
#
|
262
|
-
# @note The
|
264
|
+
# @note The dedicated handling of `Fiber` is platform dependent!
|
263
265
|
#
|
264
266
|
# @example Inspect current instance variables
|
265
267
|
# @a = 22
|
@@ -303,19 +305,18 @@ module ImLost
|
|
303
305
|
# @return [Object] the given object
|
304
306
|
#
|
305
307
|
def vars(object)
|
306
|
-
out =
|
308
|
+
out = LineStore.new
|
307
309
|
traced = @trace.delete(object)
|
308
310
|
return _local_vars(out, object) if Binding === object
|
309
|
-
location
|
310
|
-
out << "* #{location.path}:#{location.lineno}"
|
311
|
+
out.location(Kernel.caller_locations(1, 1)[0])
|
311
312
|
return _thread_vars(out, object) if Thread === object
|
312
|
-
return _fiber_vars(out, object) if @
|
313
|
+
return _fiber_vars(out, object) if @fiber_support && Fiber === object
|
313
314
|
return _instance_vars(out, object) if defined?(object.instance_variables)
|
314
315
|
out << ' !!! unable to retrieve vars'
|
315
316
|
object
|
316
317
|
ensure
|
317
318
|
@trace[traced] = traced if traced
|
318
|
-
|
319
|
+
@output << out
|
319
320
|
end
|
320
321
|
|
321
322
|
private
|
@@ -329,10 +330,7 @@ module ImLost
|
|
329
330
|
arg
|
330
331
|
end
|
331
332
|
|
332
|
-
def _trace_all(args)
|
333
|
-
args.each { |arg| @trace[arg] = arg if _can_trace?(arg) }
|
334
|
-
args
|
335
|
-
end
|
333
|
+
def _trace_all(args) = args.each { @trace[_1] = _1 if _can_trace?(_1) }
|
336
334
|
|
337
335
|
def _trace_b(arg)
|
338
336
|
return yield(arg) if @trace.key?(arg) || !_can_trace?(arg)
|
@@ -384,20 +382,17 @@ module ImLost
|
|
384
382
|
end
|
385
383
|
|
386
384
|
def _instance_vars(out, object)
|
387
|
-
out.vars('instance variables', object.instance_variables) do |
|
388
|
-
object.instance_variable_get(
|
385
|
+
out.vars('instance variables', object.instance_variables) do |name|
|
386
|
+
object.instance_variable_get(name)
|
389
387
|
end
|
390
388
|
object
|
391
389
|
end
|
392
390
|
|
393
|
-
def _thread_identifier(
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
thread.__id__
|
399
|
-
end
|
400
|
-
} #{thread.name}".rstrip
|
391
|
+
def _thread_identifier(thr)
|
392
|
+
state = thr.status
|
393
|
+
"#{state || (state.nil? ? 'aborted' : 'terminated')} Thread #{
|
394
|
+
defined?(thr.native_thread_id) ? thr.native_thread_id : thr.__id__
|
395
|
+
} #{thr.name}".rstrip
|
401
396
|
end
|
402
397
|
end
|
403
398
|
|
@@ -456,12 +451,16 @@ module ImLost
|
|
456
451
|
def count = ids.size
|
457
452
|
|
458
453
|
# @attribute [r] empty?
|
459
|
-
# @return [Boolean]
|
454
|
+
# @return [Boolean] whether the timer store is empty or not
|
460
455
|
def empty? = ids.empty?
|
461
456
|
|
462
457
|
# @attribute [r] ids
|
463
458
|
# @return [Array<Integer>] IDs of all registered timers
|
464
|
-
def ids =
|
459
|
+
def ids = @ll.keys.keep_if { Integer === _1 }
|
460
|
+
|
461
|
+
# @attribute [r] names
|
462
|
+
# @return [Array<String>] names of all registered named timers
|
463
|
+
def names = @ll.keys.delete_if { Integer === _1 }
|
465
464
|
|
466
465
|
#
|
467
466
|
# Create and register a new named or anonymous timer.
|
@@ -487,7 +486,7 @@ module ImLost
|
|
487
486
|
#
|
488
487
|
def delete(*id_or_names)
|
489
488
|
id_or_names.flatten.each do |id|
|
490
|
-
if id
|
489
|
+
if Integer === id
|
491
490
|
del = @ll.delete(id)
|
492
491
|
@ll.delete(del[0]) if del
|
493
492
|
else
|
@@ -498,6 +497,16 @@ module ImLost
|
|
498
497
|
nil
|
499
498
|
end
|
500
499
|
|
500
|
+
#
|
501
|
+
# Delete and unregister all timers.
|
502
|
+
#
|
503
|
+
# @return [self] itself
|
504
|
+
#
|
505
|
+
def clear
|
506
|
+
@ll = {}
|
507
|
+
self
|
508
|
+
end
|
509
|
+
|
501
510
|
#
|
502
511
|
# Print the ID or name and the runtime since a timer was created.
|
503
512
|
# It includes the location.
|
@@ -508,10 +517,10 @@ module ImLost
|
|
508
517
|
# identifier or name
|
509
518
|
#
|
510
519
|
def [](id_or_name)
|
511
|
-
|
512
|
-
timer = @ll[
|
520
|
+
now = self.class.now
|
521
|
+
timer = @ll[Integer === id_or_name ? id_or_name : id_or_name.to_s]
|
513
522
|
raise(ArgumentError, "not a timer - #{id_or_name.inspect}") unless timer
|
514
|
-
@cb[timer[0], Kernel.caller_locations(1, 1)[0],
|
523
|
+
@cb[timer[0], Kernel.caller_locations(1, 1)[0], (now - timer[1]).round(4)]
|
515
524
|
timer.__id__
|
516
525
|
end
|
517
526
|
|
@@ -528,125 +537,131 @@ module ImLost
|
|
528
537
|
nil
|
529
538
|
end
|
530
539
|
|
531
|
-
|
540
|
+
private
|
541
|
+
|
532
542
|
def initialize(&block)
|
533
543
|
@cb = block
|
534
|
-
|
544
|
+
clear
|
535
545
|
end
|
536
546
|
end
|
537
547
|
|
538
|
-
class
|
548
|
+
class LineStore
|
539
549
|
def initialize(*lines) = (@lines = lines)
|
550
|
+
def to_s = (@lines << nil).join("\n")
|
540
551
|
def <<(str) = @lines << str
|
541
|
-
def location(loc) = @lines << "
|
542
|
-
def flush(dev) = dev << (@lines << nil).join("\n")
|
552
|
+
def location(loc) = @lines << "* #{loc.path}:#{loc.lineno}"
|
543
553
|
|
544
|
-
def
|
545
|
-
|
546
|
-
@lines <<
|
554
|
+
def vars(kind, names)
|
555
|
+
return @lines << " <no #{kind} defined>" if names.empty?
|
556
|
+
@lines << " > #{kind}"
|
557
|
+
names.sort!.each { @lines << " #{_1}: #{yield(_1).inspect}" }
|
558
|
+
end
|
559
|
+
end
|
560
|
+
private_constant :LineStore
|
561
|
+
|
562
|
+
class CCallLineStore < LineStore
|
563
|
+
def initialize(prefix, info, include_location)
|
564
|
+
@info = info
|
565
|
+
sig = "#{info.method_id}(#{args.join(', ')})"
|
566
|
+
case info.self
|
547
567
|
when Class, Module
|
548
|
-
"#{prefix} #{info.self}.#{
|
568
|
+
super("#{prefix} #{info.self}.#{sig}")
|
549
569
|
else
|
550
|
-
"#{prefix} #{info.defined_class}##{
|
570
|
+
super("#{prefix} #{info.defined_class}##{sig}")
|
551
571
|
end
|
572
|
+
return unless include_location
|
573
|
+
loc = location
|
574
|
+
path = loc.path
|
575
|
+
path = path[10..-2] if path.start_with?('<internal:')
|
576
|
+
@lines << " #{path}:#{loc.lineno}"
|
552
577
|
end
|
553
578
|
|
554
|
-
def
|
555
|
-
|
556
|
-
|
557
|
-
|
579
|
+
def location = @info
|
580
|
+
|
581
|
+
def args
|
582
|
+
argc = -1
|
583
|
+
@info.parameters.map do |kind, _|
|
584
|
+
argc += 1
|
585
|
+
CARG_TYPE[kind] || "arg#{argc}"
|
586
|
+
end
|
558
587
|
end
|
588
|
+
|
589
|
+
CARG_TYPE = {
|
590
|
+
rest: '*args',
|
591
|
+
keyrest: '**kwargs',
|
592
|
+
block: '&block'
|
593
|
+
}.compare_by_identity.freeze
|
559
594
|
end
|
560
|
-
private_constant :
|
595
|
+
private_constant :CCallLineStore
|
561
596
|
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
private_constant :ARG_SIG, :NO_NAME, :THREAD_STATE
|
597
|
+
class RbCallLineStore < CCallLineStore
|
598
|
+
def initialize(prefix, info, include_location)
|
599
|
+
@ctx = info.binding
|
600
|
+
super
|
601
|
+
@ctx = nil
|
602
|
+
end
|
569
603
|
|
570
|
-
|
571
|
-
|
572
|
-
|
604
|
+
def location
|
605
|
+
locations = @ctx.eval('caller_locations(7,3)')
|
606
|
+
unless locations[1].path.start_with?('<internal:prelude')
|
607
|
+
return locations[1]
|
608
|
+
end
|
609
|
+
locations[0].path.start_with?('<internal:') ? locations[0] : locations[2]
|
610
|
+
end
|
573
611
|
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
612
|
+
def args
|
613
|
+
@info.parameters.map do |kind, name|
|
614
|
+
next name if ARG_SKIP.key?(name)
|
615
|
+
"#{ARG_TYPE[kind]}#{@ctx.local_variable_get(name).inspect}"
|
616
|
+
end
|
617
|
+
end
|
579
618
|
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
end,
|
588
|
-
TracePoint.new(:call) do |tp|
|
619
|
+
ARG_TYPE = { rest: :*, keyrest: :**, block: :& }.compare_by_identity.freeze
|
620
|
+
ARG_SKIP = ARG_TYPE.invert.compare_by_identity.freeze
|
621
|
+
end
|
622
|
+
private_constant :RbCallLineStore
|
623
|
+
|
624
|
+
@trace_calls =
|
625
|
+
TracePoint.new(:c_call, :call) do |tp|
|
589
626
|
next if !@trace.key?(tp.self) || tp.path == __FILE__
|
590
|
-
|
591
|
-
|
592
|
-
out.sig(
|
593
|
-
'>',
|
594
|
-
tp,
|
595
|
-
tp.parameters.map do |kind, name|
|
596
|
-
next name if NO_NAME.key?(name)
|
597
|
-
"#{ARG_SIG[kind]}#{ctx.local_variable_get(name).inspect}"
|
598
|
-
end
|
599
|
-
)
|
600
|
-
out.location(ctx.eval('caller_locations(4,1)')[0]) if @caller_locations
|
601
|
-
out.flush(@output)
|
627
|
+
klass = tp.event == :c_call ? CCallLineStore : RbCallLineStore
|
628
|
+
@output << klass.new('>', tp, @caller_locations).to_s
|
602
629
|
end
|
603
|
-
]
|
604
630
|
|
605
|
-
@trace_results =
|
606
|
-
TracePoint.new(:c_return) do |tp|
|
631
|
+
@trace_results =
|
632
|
+
TracePoint.new(:c_return, :return) do |tp|
|
607
633
|
next if !@trace.key?(tp.self) || tp.path == __FILE__
|
608
|
-
|
609
|
-
out.
|
610
|
-
out.location(tp) if @caller_locations
|
611
|
-
out << " = #{tp.return_value.inspect}"
|
612
|
-
out.flush(@output)
|
613
|
-
end,
|
614
|
-
TracePoint.new(:return) do |tp|
|
615
|
-
next if !@trace.key?(tp.self) || tp.path == __FILE__
|
616
|
-
ctx = tp.binding
|
617
|
-
out = Out.new
|
618
|
-
out.sig(
|
619
|
-
'<',
|
620
|
-
tp,
|
621
|
-
tp.parameters.map do |kind, name|
|
622
|
-
next name if NO_NAME.key?(name)
|
623
|
-
"#{ARG_SIG[kind]}#{ctx.local_variable_get(name).inspect}"
|
624
|
-
end
|
625
|
-
)
|
626
|
-
out.location(ctx.eval('caller_locations(4,1)')[0]) if @caller_locations
|
634
|
+
klass = tp.event == :c_return ? CCallLineStore : RbCallLineStore
|
635
|
+
out = klass.new('<', tp, @caller_locations)
|
627
636
|
out << " = #{tp.return_value.inspect}"
|
628
|
-
out.
|
637
|
+
@output << out.to_s
|
629
638
|
end
|
630
|
-
]
|
631
639
|
|
632
|
-
|
640
|
+
exception_support = RUBY_VERSION.to_f < 3.3 ? %i[raise] : %i[raise rescue]
|
633
641
|
@trace_exceptions =
|
634
|
-
TracePoint.new(*
|
642
|
+
TracePoint.new(*exception_support) do |tp|
|
635
643
|
ex = tp.raised_exception
|
636
644
|
mark, parent = tp.event == :rescue ? ['!', ex.cause] : 'x'
|
637
645
|
ex = ex.inspect
|
638
|
-
out =
|
646
|
+
out = LineStore.new("#{mark} #{ex[0] == '#' ? ex[2..-2] : ex}")
|
639
647
|
while parent
|
640
648
|
ex = parent.inspect
|
641
649
|
out << " [#{ex[0] == '#' ? ex[2..-2] : ex}]"
|
642
650
|
parent = parent.cause
|
643
651
|
end
|
644
|
-
out.
|
645
|
-
out.
|
652
|
+
out << " #{tp.path}:#{tp.lineno}" if @exception_locations
|
653
|
+
@output << out.to_s
|
646
654
|
end
|
647
655
|
|
648
|
-
@
|
649
|
-
|
656
|
+
@timer = TimerStore.new { |title, location, time| @output << <<~TIMER_MSG }
|
657
|
+
T #{title}: #{time ? "#{time} sec." : 'created'}
|
658
|
+
#{location.path}:#{location.lineno}
|
659
|
+
TIMER_MSG
|
660
|
+
TimerStore.private_class_method(:new)
|
650
661
|
|
662
|
+
untrace_all!
|
663
|
+
@output = STDERR
|
664
|
+
@fiber_support = !!defined?(Fiber.current.storage)
|
665
|
+
@caller_locations = @exception_locations = true
|
651
666
|
self.trace_calls = self.trace_results = true
|
652
667
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: im-lost
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Blumtritt
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
12
|
description: |
|
14
13
|
If you have overlooked something again and don't really understand what
|
@@ -19,12 +18,11 @@ description: |
|
|
19
18
|
ImLost helps you by analyzing function calls of objects, informing you
|
20
19
|
about exceptions and logging your way through your code. In short, ImLost
|
21
20
|
is your debugging helper!
|
22
|
-
email:
|
23
21
|
executables: []
|
24
22
|
extensions: []
|
25
23
|
extra_rdoc_files:
|
26
|
-
- README.md
|
27
24
|
- LICENSE
|
25
|
+
- README.md
|
28
26
|
files:
|
29
27
|
- LICENSE
|
30
28
|
- README.md
|
@@ -42,7 +40,6 @@ metadata:
|
|
42
40
|
bug_tracker_uri: https://github.com/mblumtritt/im-lost/issues
|
43
41
|
documentation_uri: https://rubydoc.info/gems/im-lost
|
44
42
|
rubygems_mfa_required: 'true'
|
45
|
-
post_install_message:
|
46
43
|
rdoc_options: []
|
47
44
|
require_paths:
|
48
45
|
- lib
|
@@ -57,8 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
54
|
- !ruby/object:Gem::Version
|
58
55
|
version: '0'
|
59
56
|
requirements: []
|
60
|
-
rubygems_version: 3.
|
61
|
-
signing_key:
|
57
|
+
rubygems_version: 3.6.8
|
62
58
|
specification_version: 4
|
63
59
|
summary: Your debugging helper.
|
64
60
|
test_files: []
|