im-lost 1.0.0 → 1.0.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/README.md +51 -20
- data/examples/foo.rb +20 -6
- data/lib/im-lost/version.rb +1 -1
- data/lib/im-lost.rb +83 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b3508c022462842507ce749828e2c74c4db9e9097496e68cedc758018017cb5
|
4
|
+
data.tar.gz: 93ac54d98ae6474d4f7144b116cf0e2784c88babf57ff592a317b463caa7ee13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d45f27c98a6ed477ce4e696f4c41286ca24c105de1668889bf64fc0d57d3947e04c026b40fa7f5f79e2ce5016fcc8327e3c9a8b20a1e6ae0561900efae4f5f3
|
7
|
+
data.tar.gz: 1502147a826924c39988f9272d62e3c0274dc8cdb961f25c405a229cf6273142579ad136af1972c06874d13af110486b79db45907c219bd3082a91cd507220ab
|
data/README.md
CHANGED
@@ -20,14 +20,14 @@ File.open('test.txt', 'w') do |file|
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
# output will look like
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
23
|
+
# > IO#<<(?)
|
24
|
+
# /projects/test.rb:1
|
25
|
+
# > IO#write(*)
|
26
|
+
# /projects/test.rb:1
|
27
|
+
# > IO#puts(*)
|
28
|
+
# /projects/test.rb:2
|
29
|
+
# > IO#write(*)
|
30
|
+
# /projects/test.rb:2
|
31
31
|
```
|
32
32
|
|
33
33
|
When you need to know if exceptions are raised and handled you can use `ImLost.trace_exceptions`:
|
@@ -39,12 +39,12 @@ rescue SystemCallError
|
|
39
39
|
raise('something went wrong!')
|
40
40
|
end
|
41
41
|
# output will look like
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
42
|
+
# x Errno::EEXIST: File exists @ rb_sysopen - /
|
43
|
+
# /projects/test.rb:2
|
44
|
+
# ! Errno::EEXIST: File exists @ rb_sysopen - /
|
45
|
+
# /projects/test.rb:3
|
46
|
+
# x RuntimeError: something went wrong!
|
47
|
+
# /projects/test.rb:4
|
48
48
|
```
|
49
49
|
|
50
50
|
When you like to know if and when a code point is reached, `ImLost.here` will help:
|
@@ -53,11 +53,28 @@ When you like to know if and when a code point is reached, `ImLost.here` will he
|
|
53
53
|
ImLost.here
|
54
54
|
```
|
55
55
|
|
56
|
+
If you like to know the instance variables values of an object, use
|
57
|
+
`ImLost.vars`:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
ImLost.vars(self)
|
61
|
+
```
|
62
|
+
|
63
|
+
Or you can print the current local variables:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
ImLost.vars(binding)
|
67
|
+
```
|
68
|
+
|
69
|
+
See the [online help](https://rubydoc.info/gems/im-lost/ImLost) for more!
|
70
|
+
|
56
71
|
## Example
|
57
72
|
|
58
73
|
```ruby
|
59
74
|
require 'im-lost'
|
60
75
|
|
76
|
+
require_relative '../lib/im-lost'
|
77
|
+
|
61
78
|
class Foo
|
62
79
|
def self.create(value:) = new(value)
|
63
80
|
|
@@ -82,8 +99,13 @@ my_foo = Foo.create(value: :foo!)
|
|
82
99
|
ImLost.trace(my_foo)
|
83
100
|
|
84
101
|
my_foo.foo(1, key: :none)
|
102
|
+
ImLost.vars(my_foo)
|
103
|
+
|
85
104
|
my_foo.foo(2, :a, :b, :c, key: :some, name: :value)
|
105
|
+
ImLost.vars(my_foo)
|
106
|
+
|
86
107
|
my_foo.foo(3) { puts _1 }
|
108
|
+
ImLost.vars(my_foo)
|
87
109
|
|
88
110
|
# output will look like
|
89
111
|
# > Foo.create(:foo!)
|
@@ -91,9 +113,9 @@ my_foo.foo(3) { puts _1 }
|
|
91
113
|
# > Foo.new(*)
|
92
114
|
# /projects/foo.rb:6
|
93
115
|
# < Foo.new(*)
|
94
|
-
# = #<Foo:
|
116
|
+
# = #<Foo:0x00000001030810c0 @value=:foo!>
|
95
117
|
# < Foo.create(:foo!)
|
96
|
-
# = #<Foo:
|
118
|
+
# = #<Foo:0x00000001030810c0 @value=:foo!>
|
97
119
|
# > Foo#foo(1, *[], :none, **{}, &nil)
|
98
120
|
# /projects/foo.rb:28
|
99
121
|
# > Foo#bar()
|
@@ -102,23 +124,32 @@ my_foo.foo(3) { puts _1 }
|
|
102
124
|
# = :bar
|
103
125
|
# < Foo#foo(1, *[], :none, **{}, &nil)
|
104
126
|
# = "1-none-[]-{}-bar"
|
127
|
+
# = /projects/foo.rb:29
|
128
|
+
# instance variables:
|
129
|
+
# @value: "1-none-[]-{}-bar"
|
105
130
|
# > Foo#foo(2, *[:a, :b, :c], :some, **{:name=>:value}, &nil)
|
106
|
-
# /projects/foo.rb:
|
131
|
+
# /projects/foo.rb:31
|
107
132
|
# > Foo#bar()
|
108
133
|
# /projects/foo.rb:15
|
109
134
|
# < Foo#bar()
|
110
135
|
# = :bar
|
111
136
|
# < Foo#foo(2, *[:a, :b, :c], :some, **{:name=>:value}, &nil)
|
112
137
|
# = "2-some-[a,b,c]-{:name=>:value}-bar"
|
113
|
-
#
|
114
|
-
#
|
138
|
+
# = /projects/foo.rb:32
|
139
|
+
# instance variables:
|
140
|
+
# @value: "2-some-[a,b,c]-{:name=>:value}-bar"
|
141
|
+
# > Foo#foo(3, *[], nil, **{}, &#<Proc:0x00000001030aee30 /projects/foo.rb:34>)
|
142
|
+
# /projects/foo.rb:34
|
115
143
|
# > Foo#bar()
|
116
144
|
# /projects/foo.rb:15
|
117
145
|
# < Foo#bar()
|
118
146
|
# = :bar
|
119
147
|
# 3--[]-{}-bar
|
120
|
-
# < Foo#foo(3, *[], nil, **{}, &#<Proc:
|
148
|
+
# < Foo#foo(3, *[], nil, **{}, &#<Proc:0x00000001030aee30 /projects/foo.rb:34>)
|
121
149
|
# = nil
|
150
|
+
# = /projects/foo.rb:35
|
151
|
+
# instance variables:
|
152
|
+
# @value: "3--[]-{}-bar"
|
122
153
|
```
|
123
154
|
|
124
155
|
See [examples dir](./examples) for more…
|
data/examples/foo.rb
CHANGED
@@ -26,8 +26,13 @@ my_foo = Foo.create(value: :foo!)
|
|
26
26
|
ImLost.trace(my_foo)
|
27
27
|
|
28
28
|
my_foo.foo(1, key: :none)
|
29
|
+
ImLost.vars(my_foo)
|
30
|
+
|
29
31
|
my_foo.foo(2, :a, :b, :c, key: :some, name: :value)
|
32
|
+
ImLost.vars(my_foo)
|
33
|
+
|
30
34
|
my_foo.foo(3) { puts _1 }
|
35
|
+
ImLost.vars(my_foo)
|
31
36
|
|
32
37
|
# output will look like
|
33
38
|
# > Foo.create(:foo!)
|
@@ -35,9 +40,9 @@ my_foo.foo(3) { puts _1 }
|
|
35
40
|
# > Foo.new(*)
|
36
41
|
# /projects/foo.rb:6
|
37
42
|
# < Foo.new(*)
|
38
|
-
# = #<Foo:
|
43
|
+
# = #<Foo:0x00000001030810c0 @value=:foo!>
|
39
44
|
# < Foo.create(:foo!)
|
40
|
-
# = #<Foo:
|
45
|
+
# = #<Foo:0x00000001030810c0 @value=:foo!>
|
41
46
|
# > Foo#foo(1, *[], :none, **{}, &nil)
|
42
47
|
# /projects/foo.rb:28
|
43
48
|
# > Foo#bar()
|
@@ -46,20 +51,29 @@ my_foo.foo(3) { puts _1 }
|
|
46
51
|
# = :bar
|
47
52
|
# < Foo#foo(1, *[], :none, **{}, &nil)
|
48
53
|
# = "1-none-[]-{}-bar"
|
54
|
+
# = /projects/foo.rb:29
|
55
|
+
# instance variables:
|
56
|
+
# @value: "1-none-[]-{}-bar"
|
49
57
|
# > Foo#foo(2, *[:a, :b, :c], :some, **{:name=>:value}, &nil)
|
50
|
-
# /projects/foo.rb:
|
58
|
+
# /projects/foo.rb:31
|
51
59
|
# > Foo#bar()
|
52
60
|
# /projects/foo.rb:15
|
53
61
|
# < Foo#bar()
|
54
62
|
# = :bar
|
55
63
|
# < Foo#foo(2, *[:a, :b, :c], :some, **{:name=>:value}, &nil)
|
56
64
|
# = "2-some-[a,b,c]-{:name=>:value}-bar"
|
57
|
-
#
|
58
|
-
#
|
65
|
+
# = /projects/foo.rb:32
|
66
|
+
# instance variables:
|
67
|
+
# @value: "2-some-[a,b,c]-{:name=>:value}-bar"
|
68
|
+
# > Foo#foo(3, *[], nil, **{}, &#<Proc:0x00000001030aee30 /projects/foo.rb:34>)
|
69
|
+
# /projects/foo.rb:34
|
59
70
|
# > Foo#bar()
|
60
71
|
# /projects/foo.rb:15
|
61
72
|
# < Foo#bar()
|
62
73
|
# = :bar
|
63
74
|
# 3--[]-{}-bar
|
64
|
-
# < Foo#foo(3, *[], nil, **{}, &#<Proc:
|
75
|
+
# < Foo#foo(3, *[], nil, **{}, &#<Proc:0x00000001030aee30 /projects/foo.rb:34>)
|
65
76
|
# = nil
|
77
|
+
# = /projects/foo.rb:35
|
78
|
+
# instance variables:
|
79
|
+
# @value: "3--[]-{}-bar"
|
data/lib/im-lost/version.rb
CHANGED
data/lib/im-lost.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# If you have overlooked something again and don't really understand what your
|
4
|
+
# code is doing. If you have to maintain this application but can't really find
|
5
|
+
# your way around and certainly can't track down that stupid error. If you feel
|
6
|
+
# lost in all that code, here's the gem to help you out!
|
7
|
+
#
|
8
|
+
# ImLost helps you by analyzing function calls of objects, informing you about
|
9
|
+
# exceptions and logging your way through your code. In short, ImLost is your
|
10
|
+
# debugging helper!
|
11
|
+
#
|
3
12
|
module ImLost
|
4
13
|
class << self
|
5
14
|
#
|
@@ -226,6 +235,28 @@ module ImLost
|
|
226
235
|
self
|
227
236
|
end
|
228
237
|
|
238
|
+
#
|
239
|
+
# Inspect internal variables.
|
240
|
+
#
|
241
|
+
# @overload vars(binding)
|
242
|
+
# Inspect local variables of given Binding.
|
243
|
+
# @param binding [Binding] which local variables should be print
|
244
|
+
# @return [self] itself
|
245
|
+
#
|
246
|
+
# @overload vars(object)
|
247
|
+
# Inspect instance variables of given object.
|
248
|
+
# @param object [Object] which instance variables should be print
|
249
|
+
# @return [Object] the given object
|
250
|
+
#
|
251
|
+
def vars(object)
|
252
|
+
traced = @trace.delete(object.__id__)
|
253
|
+
return _local_vars(object) if object.is_a?(Binding)
|
254
|
+
return unless object.respond_to?(:instance_variables)
|
255
|
+
_vars(object, Kernel.caller_locations(1, 1)[0])
|
256
|
+
ensure
|
257
|
+
@trace[traced] = traced if traced
|
258
|
+
end
|
259
|
+
|
229
260
|
protected
|
230
261
|
|
231
262
|
def as_sig(prefix, info, args)
|
@@ -241,41 +272,73 @@ module ImLost
|
|
241
272
|
private
|
242
273
|
|
243
274
|
def _trace(arg)
|
244
|
-
|
275
|
+
id = arg.__id__
|
276
|
+
@trace[id] = id if __id__ != id && @output.__id__ != id
|
245
277
|
arg
|
246
278
|
end
|
247
279
|
|
248
280
|
def _trace_all(args)
|
249
281
|
args.each do |arg|
|
250
|
-
|
282
|
+
arg = arg.__id__
|
283
|
+
@trace[arg] = arg if __id__ != arg && @output.__id__ != arg
|
251
284
|
end
|
252
285
|
args
|
253
286
|
end
|
254
287
|
|
255
288
|
def _trace_b(arg)
|
256
|
-
|
257
|
-
yield(arg)
|
258
|
-
|
259
|
-
|
289
|
+
id = arg.__id__
|
290
|
+
return yield(arg) if __id__ == id || @output.__id__ == id
|
291
|
+
begin
|
292
|
+
@trace[id] = id
|
293
|
+
yield(arg)
|
294
|
+
ensure
|
295
|
+
@trace.delete(id) if id
|
296
|
+
end
|
260
297
|
end
|
261
298
|
|
262
299
|
def _trace_all_b(args)
|
263
300
|
ids =
|
264
301
|
args.filter_map do |arg|
|
265
|
-
|
266
|
-
@trace[
|
267
|
-
id
|
302
|
+
arg = arg.__id__
|
303
|
+
@trace[arg] = arg if __id__ != arg && @output.__id__ != arg
|
268
304
|
end
|
269
305
|
yield(args)
|
270
306
|
ensure
|
271
307
|
ids.each { @trace.delete(_1) }
|
272
308
|
end
|
309
|
+
|
310
|
+
def _vars(obj, location)
|
311
|
+
@output.puts("= #{location.path}:#{location.lineno}")
|
312
|
+
vars = obj.instance_variables
|
313
|
+
if vars.empty?
|
314
|
+
@output.puts(' <no instance variables defined>')
|
315
|
+
else
|
316
|
+
@output.puts(' instance variables:')
|
317
|
+
vars.sort!.each do |name|
|
318
|
+
@output.puts(" #{name}: #{obj.instance_variable_get(name).inspect}")
|
319
|
+
end
|
320
|
+
end
|
321
|
+
obj
|
322
|
+
end
|
323
|
+
|
324
|
+
def _local_vars(binding)
|
325
|
+
@output.puts("= #{binding.source_location.join(':')}")
|
326
|
+
vars = binding.local_variables
|
327
|
+
if vars.empty?
|
328
|
+
@output.puts(' <no local variables>')
|
329
|
+
else
|
330
|
+
@output.puts(' local variables:')
|
331
|
+
vars.sort!.each do |name|
|
332
|
+
@output.puts(" #{name}: #{binding.local_variable_get(name).inspect}")
|
333
|
+
end
|
334
|
+
end
|
335
|
+
self
|
336
|
+
end
|
273
337
|
end
|
274
338
|
|
275
339
|
ARG_SIG = { rest: '*', keyrest: '**', block: '&' }.compare_by_identity.freeze
|
276
|
-
NO_NAME =
|
277
|
-
|
278
|
-
private_constant :ARG_SIG, :NO_NAME, :EX_PREFIX
|
340
|
+
NO_NAME = { :* => 1, :** => 1, :& => 1 }.compare_by_identity.freeze
|
341
|
+
private_constant :ARG_SIG, :NO_NAME
|
279
342
|
|
280
343
|
@trace = {}.compare_by_identity
|
281
344
|
@caller_locations = true
|
@@ -283,19 +346,19 @@ module ImLost
|
|
283
346
|
|
284
347
|
@trace_calls = [
|
285
348
|
TracePoint.new(:c_call) do |tp|
|
286
|
-
next
|
349
|
+
next if !@trace.key?(tp.self.__id__) || tp.path == __FILE__
|
287
350
|
@output.puts(as_sig('>', tp, tp.parameters.map { ARG_SIG[_1[0]] || '?' }))
|
288
351
|
@output.puts(" #{tp.path}:#{tp.lineno}") if @caller_locations
|
289
352
|
end,
|
290
353
|
TracePoint.new(:call) do |tp|
|
291
|
-
next
|
354
|
+
next if !@trace.key?(tp.self.__id__) || tp.path == __FILE__
|
292
355
|
ctx = tp.binding
|
293
356
|
@output.puts(
|
294
357
|
as_sig(
|
295
358
|
'>',
|
296
359
|
tp,
|
297
360
|
tp.parameters.map do |kind, name|
|
298
|
-
next name if NO_NAME.
|
361
|
+
next name if NO_NAME.key?(name)
|
299
362
|
"#{ARG_SIG[kind]}#{ctx.local_variable_get(name).inspect}"
|
300
363
|
end
|
301
364
|
)
|
@@ -308,12 +371,12 @@ module ImLost
|
|
308
371
|
|
309
372
|
@trace_results = [
|
310
373
|
TracePoint.new(:c_return) do |tp|
|
311
|
-
next
|
374
|
+
next if !@trace.key?(tp.self.__id__) || tp.path == __FILE__
|
312
375
|
@output.puts(as_sig('<', tp, tp.parameters.map { ARG_SIG[_1[0]] || '?' }))
|
313
376
|
@output.puts(" = #{tp.return_value.inspect}")
|
314
377
|
end,
|
315
378
|
TracePoint.new(:return) do |tp|
|
316
|
-
next
|
379
|
+
next if !@trace.key?(tp.self.__id__) || tp.path == __FILE__
|
317
380
|
ctx = tp.binding
|
318
381
|
@output.puts(
|
319
382
|
as_sig(
|
@@ -333,7 +396,9 @@ module ImLost
|
|
333
396
|
@trace_exceptions =
|
334
397
|
TracePoint.new(*supported) do |tp|
|
335
398
|
ex = tp.raised_exception.inspect
|
336
|
-
@output.puts(
|
399
|
+
@output.puts(
|
400
|
+
"#{tp.event == :raise ? 'x' : '!'} #{ex[0] == '#' ? ex[2..-2] : ex}"
|
401
|
+
)
|
337
402
|
@output.puts(" #{tp.path}:#{tp.lineno}") if @exception_locations
|
338
403
|
end
|
339
404
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: im-lost
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Blumtritt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
If you have overlooked something again and don't really understand what
|