puts_debuggerer 0.10.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +140 -72
- data/VERSION +1 -1
- data/lib/puts_debuggerer.rb +44 -221
- data/lib/puts_debuggerer/core_ext/kernel.rb +218 -0
- data/lib/puts_debuggerer/core_ext/logger.rb +3 -0
- data/lib/puts_debuggerer/core_ext/logging/logger.rb +5 -0
- data/lib/puts_debuggerer/run_determiner.rb +7 -7
- data/lib/puts_debuggerer/source_file.rb +4 -3
- metadata +17 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9dcb8700ea76c5b172428f7a4c08285244da367442f8a5bb90b45d1c25f7b107
|
4
|
+
data.tar.gz: ee730414f3252a164a5ff1d0f4321564dc9c11e36e72f7e2f63998128dbf2c1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40dcf3829312a9d2d30f77371c7296d0f4511d41917263e26248d8d9add0950847effe52a1afb4cec823e8afa4449426a4ab5e2f2aa86e107458aca4ac78ee4a
|
7
|
+
data.tar.gz: efc7adc8820b1ff2a483e88e4255a3dc3280fee16d22750a079e16c7f4de82023d811efa0dbf47e100cb4777e518e7c2c845c70a01878b47e8aa5b67ac9c99c4
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.13.0
|
4
|
+
|
5
|
+
- Support `h: :t` shortcut to passing `header: true`
|
6
|
+
- Support `f: :t` shortcut to passing `footer: true`
|
7
|
+
- Support `w: :t` shortcut to passing `wrapper: true`
|
8
|
+
|
9
|
+
## 0.12.0
|
10
|
+
|
11
|
+
- Upgrade `awesome_print` to `~> 1.9.2`
|
12
|
+
- Support passing pd options as part of a printed hash instead of requiring a separate hash (e.g. `pd(path: path, header: true)` instead of `pd({path: path}, header: true)` )
|
13
|
+
- Support empty use of pd statement + options (e.g. `pd` or `pd header: true`)
|
14
|
+
|
15
|
+
## 0.11.0
|
16
|
+
|
17
|
+
- Pry support
|
18
|
+
- In Opal, print exceptions as errors in the web console using an alternative to full_message since it's not implemented in Opal yet
|
19
|
+
- Fix `pd_inspect` and `pdi` in IRB
|
20
|
+
|
21
|
+
## 0.10.2
|
22
|
+
|
23
|
+
- Improve Opal Ruby compatibility by displaying source file/line
|
24
|
+
|
25
|
+
## 0.10.1
|
26
|
+
|
27
|
+
- Remove the need for specifying `require 'ap'` before `require 'pd'`
|
28
|
+
|
3
29
|
## 0.10.0
|
4
30
|
|
5
31
|
- Support `require 'pd`' as a shorter alternative to `require 'puts_debuggerer'`
|
data/README.md
CHANGED
@@ -12,13 +12,13 @@ In day-to-day test-driven development and simple app debugging though, a puts st
|
|
12
12
|
|
13
13
|
Enter [puts_debuggerer](https://rubygems.org/gems/puts_debuggerer)! A guilt-free puts debugging Ruby gem FTW that prints file names, line numbers, code statements, headers, footers, stack traces, and formats output nicely courtesy of [awesome_print](https://rubygems.org/gems/awesome_print).
|
14
14
|
|
15
|
-
[puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) automates tips mentioned in [this blog post](https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html) by Aaron Patterson.
|
15
|
+
[puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) automates tips mentioned in [this blog post](https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html) by Aaron Patterson using the `pd` method available everywhere after requiring the [gem](https://rubygems.org/gems/puts_debuggerer).
|
16
16
|
|
17
17
|
Basic Example:
|
18
18
|
|
19
19
|
```ruby
|
20
20
|
# /Users/User/trivia_app.rb # line 1
|
21
|
-
require '
|
21
|
+
require 'pd' # line 2
|
22
22
|
bug_or_band = 'beattle' # line 3
|
23
23
|
pd bug_or_band # line 4
|
24
24
|
```
|
@@ -33,7 +33,7 @@ Output:
|
|
33
33
|
|
34
34
|
## Background
|
35
35
|
|
36
|
-
It can be quite frustrating to lose puts statements in a large output or log file. One way to help find them is add an announcer (e.g. `puts "The Order Total"`) or a header (e.g. `puts '
|
36
|
+
It can be quite frustrating to lose puts statements in a large output or log file. One way to help find them is add an announcer (e.g. `puts "The Order Total"`) or a header (e.g. `puts '>'*80`) before every puts statement. Unfortunately, that leads to repetitive wasteful effort that adds up quickly over many work sessions and interrupts thinking flow while solving problems.
|
37
37
|
|
38
38
|
puts_debuggerer automates that work via the short and simple `pd` command, automatically printing meaningful headers for output and accelerating problem solving work due to ease of typing.
|
39
39
|
|
@@ -62,28 +62,6 @@ Which gets lost in a logging stream such as:
|
|
62
62
|
(0.2ms) COMMIT
|
63
63
|
```
|
64
64
|
|
65
|
-
Problem can be mitigated by adding a few more puts statements:
|
66
|
-
|
67
|
-
```ruby
|
68
|
-
puts "*"*40
|
69
|
-
puts "order_total"
|
70
|
-
puts order_total
|
71
|
-
```
|
72
|
-
|
73
|
-
But those add up pretty quickly when inspecting multiple variables:
|
74
|
-
|
75
|
-
```ruby
|
76
|
-
puts "*"*40
|
77
|
-
puts "order_total"
|
78
|
-
puts order_total
|
79
|
-
puts "*"*40
|
80
|
-
puts "order_summary"
|
81
|
-
puts order_summary
|
82
|
-
puts "*"*40
|
83
|
-
puts "order_details"
|
84
|
-
puts order_details
|
85
|
-
```
|
86
|
-
|
87
65
|
Here is a simple example using `pd` instead, which provides everything the puts statements above provide in addition to deducing the file name and line number automatically for dead easy debugging:
|
88
66
|
|
89
67
|
```ruby
|
@@ -93,9 +71,17 @@ pd order_total
|
|
93
71
|
Output:
|
94
72
|
|
95
73
|
```
|
74
|
+
(2.7ms) CREATE TABLE "ar_internal_metadata" ("key" character varying PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
|
75
|
+
ActiveRecord::InternalMetadata Load (0.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
76
|
+
(0.2ms) BEGIN
|
77
|
+
SQL (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", 2017-08-24 22:56:52 UTC], ["updated_at", 2017-08-24 22:56:52 UTC]]
|
78
|
+
(0.3ms) COMMIT
|
96
79
|
[PD] /Users/User/ordering/order.rb:39
|
97
|
-
> pd order_total
|
80
|
+
> pd order_total
|
98
81
|
=> 195.50
|
82
|
+
ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
83
|
+
(0.2ms) BEGIN
|
84
|
+
(0.2ms) COMMIT
|
99
85
|
```
|
100
86
|
|
101
87
|
This is not only easy to locate in a logging stream such as the one below, but also announces the `order_total` variable with `[PD]` for easy findability among other pd statements (you may always enter `[PD]` or variable name `order_total` using the CMD+F Quick Find to instantly jump to that line in the log):
|
@@ -112,23 +98,23 @@ Output:
|
|
112
98
|
(2.7ms) CREATE TABLE "ar_internal_metadata" ("key" character varying PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
|
113
99
|
ActiveRecord::InternalMetadata Load (0.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
114
100
|
[PD] /Users/User/ordering/order.rb:39
|
115
|
-
> pd order_total
|
101
|
+
> pd order_total
|
116
102
|
=> 195.50
|
117
103
|
(0.2ms) BEGIN
|
118
104
|
SQL (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", 2017-08-24 22:56:52 UTC], ["updated_at", 2017-08-24 22:56:52 UTC]]
|
119
105
|
(0.3ms) COMMIT
|
120
106
|
[PD] /Users/User/ordering/order.rb:40
|
121
|
-
> pd order_summary
|
107
|
+
> pd order_summary
|
122
108
|
=> "Pragmatic Ruby Book"
|
123
109
|
ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
124
110
|
(0.2ms) BEGIN
|
125
111
|
(0.2ms) COMMIT
|
126
112
|
[PD] /Users/User/ordering/order.rb:41
|
127
|
-
> pd order_details
|
113
|
+
> pd order_details
|
128
114
|
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
129
115
|
```
|
130
116
|
|
131
|
-
What if you would like to add a header for faster findability? Just use the `header` option:
|
117
|
+
What if you would like to add a header for faster findability of groups of related pd statements? Just use the `header` option (or `h`):
|
132
118
|
|
133
119
|
```ruby
|
134
120
|
pd order_total, header: true
|
@@ -141,7 +127,7 @@ Output:
|
|
141
127
|
```
|
142
128
|
(2.7ms) CREATE TABLE "ar_internal_metadata" ("key" character varying PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
|
143
129
|
ActiveRecord::InternalMetadata Load (0.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
144
|
-
|
130
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
145
131
|
[PD] /Users/User/ordering/order.rb:39
|
146
132
|
> pd order_total, header: true
|
147
133
|
=> 195.50
|
@@ -149,13 +135,13 @@ Output:
|
|
149
135
|
SQL (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", 2017-08-24 22:56:52 UTC], ["updated_at", 2017-08-24 22:56:52 UTC]]
|
150
136
|
(0.3ms) COMMIT
|
151
137
|
[PD] /Users/User/ordering/order.rb:40
|
152
|
-
> pd order_summary
|
138
|
+
> pd order_summary
|
153
139
|
=> "Pragmatic Ruby Book"
|
154
140
|
ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
155
141
|
(0.2ms) BEGIN
|
156
142
|
(0.2ms) COMMIT
|
157
143
|
[PD] /Users/User/ordering/order.rb:41
|
158
|
-
> pd order_details
|
144
|
+
> pd order_details
|
159
145
|
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
160
146
|
```
|
161
147
|
|
@@ -180,18 +166,18 @@ Output:
|
|
180
166
|
SQL (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", 2017-08-24 22:56:52 UTC], ["updated_at", 2017-08-24 22:56:52 UTC]]
|
181
167
|
(0.3ms) COMMIT
|
182
168
|
[PD] /Users/User/ordering/order.rb:40
|
183
|
-
> pd order_summary
|
169
|
+
> pd order_summary
|
184
170
|
=> "Pragmatic Ruby Book"
|
185
171
|
ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
186
172
|
(0.2ms) BEGIN
|
187
173
|
(0.2ms) COMMIT
|
188
174
|
[PD] /Users/User/ordering/order.rb:41
|
189
|
-
> pd order_details, footer: '<'*80
|
175
|
+
> pd order_details, footer: '<'*80
|
190
176
|
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
191
177
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
192
178
|
```
|
193
179
|
|
194
|
-
Need a quick stack trace? Just use the `caller` option (you may surround with header and footer too via `wrapper`).
|
180
|
+
Need a quick stack trace? Just use the `caller` option (you may surround with header and footer too via `wrapper` or `w`).
|
195
181
|
|
196
182
|
```ruby
|
197
183
|
pd order_total, caller: true, wrapper: true
|
@@ -250,13 +236,13 @@ Output:
|
|
250
236
|
SQL (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", 2017-08-24 22:56:52 UTC], ["updated_at", 2017-08-24 22:56:52 UTC]]
|
251
237
|
(0.3ms) COMMIT
|
252
238
|
[PD] /Users/User/ordering/order.rb:40
|
253
|
-
> pd order_summary
|
239
|
+
> pd order_summary
|
254
240
|
=> "Pragmatic Ruby Book"
|
255
241
|
ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
256
242
|
(0.2ms) BEGIN
|
257
243
|
(0.2ms) COMMIT
|
258
244
|
[PD] /Users/User/ordering/order.rb:41
|
259
|
-
> pd order_details
|
245
|
+
> pd order_details
|
260
246
|
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
261
247
|
```
|
262
248
|
|
@@ -273,7 +259,7 @@ pd order_details
|
|
273
259
|
ActiveRecord::InternalMetadata Load (0.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
274
260
|
********************************************************************************
|
275
261
|
[PD] /Users/User/ordering/order.rb:39
|
276
|
-
> pd order_total, caller: 3, wrapper: true
|
262
|
+
> pd order_total, caller: 3, wrapper: true
|
277
263
|
=> 195.50
|
278
264
|
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
|
279
265
|
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
|
@@ -283,17 +269,17 @@ pd order_details
|
|
283
269
|
SQL (0.3ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "development"], ["created_at", 2017-08-24 22:56:52 UTC], ["updated_at", 2017-08-24 22:56:52 UTC]]
|
284
270
|
(0.3ms) COMMIT
|
285
271
|
[PD] /Users/User/ordering/order.rb:40
|
286
|
-
> pd order_summary
|
272
|
+
> pd order_summary
|
287
273
|
=> "Pragmatic Ruby Book"
|
288
274
|
ActiveRecord::InternalMetadata Load (0.3ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", :environment], ["LIMIT", 1]]
|
289
275
|
(0.2ms) BEGIN
|
290
276
|
(0.2ms) COMMIT
|
291
277
|
[PD] /Users/User/ordering/order.rb:41
|
292
|
-
> pd order_details
|
278
|
+
> pd order_details
|
293
279
|
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
294
280
|
```
|
295
281
|
|
296
|
-
There are many more options and
|
282
|
+
There are many more options and features in [puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) as detailed below.
|
297
283
|
|
298
284
|
## Instructions
|
299
285
|
|
@@ -302,7 +288,7 @@ There are many more options and powerful features in [puts_debuggerer](https://r
|
|
302
288
|
Add the following to bundler's `Gemfile`.
|
303
289
|
|
304
290
|
```ruby
|
305
|
-
gem 'puts_debuggerer', '~> 0.
|
291
|
+
gem 'puts_debuggerer', '~> 0.13.0'
|
306
292
|
```
|
307
293
|
|
308
294
|
This is the recommended way for [Rails](rubyonrails.org) apps. Optionally, you may create an initializer under `config/initializers` named `puts_debuggerer_options.rb` to enable further customizations as per the [Options](#options) section below.
|
@@ -312,18 +298,34 @@ This is the recommended way for [Rails](rubyonrails.org) apps. Optionally, you m
|
|
312
298
|
Or manually install and require library.
|
313
299
|
|
314
300
|
```bash
|
315
|
-
gem install puts_debuggerer -v0.
|
301
|
+
gem install puts_debuggerer -v0.13.0
|
316
302
|
```
|
317
303
|
|
318
304
|
```ruby
|
319
305
|
require 'puts_debuggerer'
|
320
306
|
```
|
321
307
|
|
308
|
+
Or the shorter form (often helpful to quickly troubleshoot an app):
|
309
|
+
|
310
|
+
```ruby
|
311
|
+
require 'pd'
|
312
|
+
```
|
313
|
+
|
322
314
|
### Awesome Print
|
323
315
|
|
324
|
-
puts_debuggerer comes with [awesome_print](https://github.com/awesome-print/awesome_print).
|
316
|
+
[puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) comes with [awesome_print](https://github.com/awesome-print/awesome_print).
|
317
|
+
|
318
|
+
It is the default `PutsDebuggerer.print_engine`
|
325
319
|
|
326
|
-
|
320
|
+
Still, if you do not need it, you may disable by setting `PutsDebuggerer.print_engine` to another value. Example:
|
321
|
+
|
322
|
+
```ruby
|
323
|
+
PutsDebuggerer.print_engine = :puts
|
324
|
+
```
|
325
|
+
|
326
|
+
If you also avoid requiring 'awesome_print', PutsDebuggerer won't require it either if it sees that you have a different `print_engine`
|
327
|
+
|
328
|
+
You may also avoid requiring in Bundler `Gemfile` with `require: false`:
|
327
329
|
|
328
330
|
```ruby
|
329
331
|
gem "awesome_print", require: false
|
@@ -354,7 +356,7 @@ Output:
|
|
354
356
|
=> "Show me the result of the calculation: 4.0"
|
355
357
|
```
|
356
358
|
|
357
|
-
In addition to the main object/expression output, you get to see the source file name, line number, and source code to help you debug and troubleshoot problems quicker (it even works in IRB).
|
359
|
+
In addition to the main object/expression output, you get to see the source file name, line number, and source code to help you debug and troubleshoot problems quicker (it even works in IRB and Pry).
|
358
360
|
|
359
361
|
Second, quickly locate printed lines using the Find feature (e.g. CTRL+F) by looking for:
|
360
362
|
* [PD]
|
@@ -381,14 +383,21 @@ Output:
|
|
381
383
|
=> "Hello Robert"
|
382
384
|
```
|
383
385
|
|
384
|
-
Alternatively, you may want to use `object.pd_inspect` (or alias `obj.pdi`) to
|
385
|
-
return formatted string without printing.
|
386
|
-
|
387
386
|
Happy puts_debuggerering!
|
388
387
|
|
389
|
-
####
|
388
|
+
#### `pd_inspect` kernel method
|
390
389
|
|
391
|
-
|
390
|
+
You may want to just return the string produced by the `pd` method without printing it.
|
391
|
+
|
392
|
+
In that case, you may use the `pd` alternative to `object.inspect`:
|
393
|
+
- `object.pd_inspect`
|
394
|
+
- `obj.pdi` (shorter alias)
|
395
|
+
|
396
|
+
This returns the `pd` formatted string without printing to the terminal or log files.
|
397
|
+
|
398
|
+
#### Ruby Logger and Logging::Logger
|
399
|
+
|
400
|
+
Ruby Logger and Logging::Logger (from [logging gem](https://github.com/TwP/logging)) are supported as [printers](#putsdebuggererprinter) (learn more under [PutsDebuggerer#printer](#putsdebuggererprinter)).
|
392
401
|
|
393
402
|
### Options
|
394
403
|
|
@@ -412,7 +421,7 @@ pd data, header: true
|
|
412
421
|
Prints out:
|
413
422
|
|
414
423
|
```bash
|
415
|
-
|
424
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
416
425
|
[PD] /Users/User/project/piecemeal.rb:3
|
417
426
|
> pd data, header: true
|
418
427
|
=> [1, [2, 3]]
|
@@ -461,11 +470,11 @@ Example Printout:
|
|
461
470
|
```
|
462
471
|
|
463
472
|
#### `PutsDebuggerer.header`
|
464
|
-
(default = `'
|
473
|
+
(default = `'>'*80`)
|
465
474
|
|
466
475
|
Header to include at the top of every print out.
|
467
476
|
* Default value is `nil`
|
468
|
-
* Value `true` enables header as `'
|
477
|
+
* Value `true` enables header as `'>'*80`
|
469
478
|
* Value `false`, `nil`, or empty string disables header
|
470
479
|
* Any other string value gets set as a custom header
|
471
480
|
|
@@ -478,12 +487,27 @@ pd (x=1), header: true
|
|
478
487
|
Prints out:
|
479
488
|
|
480
489
|
```bash
|
481
|
-
|
490
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
482
491
|
[PD] /Users/User/example.rb:1
|
483
492
|
> pd (x=1), header: true
|
484
493
|
=> "1"
|
485
494
|
```
|
486
495
|
|
496
|
+
Shortcut Example:
|
497
|
+
|
498
|
+
```ruby
|
499
|
+
pd (x=1), h: :t
|
500
|
+
```
|
501
|
+
|
502
|
+
Prints out:
|
503
|
+
|
504
|
+
```bash
|
505
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
506
|
+
[PD] /Users/User/example.rb:1
|
507
|
+
> pd (x=1), h: :t
|
508
|
+
=> "1"
|
509
|
+
```
|
510
|
+
|
487
511
|
Global Option Example:
|
488
512
|
|
489
513
|
```ruby
|
@@ -495,22 +519,22 @@ pd (x=2)
|
|
495
519
|
Prints out:
|
496
520
|
|
497
521
|
```bash
|
498
|
-
|
522
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
499
523
|
[PD] /Users/User/example.rb:2
|
500
524
|
> pd (x=1)
|
501
525
|
=> "1"
|
502
|
-
|
526
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
503
527
|
[PD] /Users/User/example.rb:3
|
504
528
|
> pd (x=2)
|
505
529
|
=> "2"
|
506
530
|
```
|
507
531
|
|
508
532
|
#### `PutsDebuggerer.footer`
|
509
|
-
(default = `'
|
533
|
+
(default = `'<'*80`)
|
510
534
|
|
511
535
|
Footer to include at the bottom of every print out.
|
512
536
|
* Default value is `nil`
|
513
|
-
* Value `true` enables footer as `'
|
537
|
+
* Value `true` enables footer as `'<'*80`
|
514
538
|
* Value `false`, `nil`, or empty string disables footer
|
515
539
|
* Any other string value gets set as a custom footer
|
516
540
|
|
@@ -526,7 +550,22 @@ Prints out:
|
|
526
550
|
[PD] /Users/User/example.rb:1
|
527
551
|
> pd (x=1), footer: true
|
528
552
|
=> "1"
|
529
|
-
|
553
|
+
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
554
|
+
```
|
555
|
+
|
556
|
+
Shortcut Example:
|
557
|
+
|
558
|
+
```ruby
|
559
|
+
pd (x=1), f: :t
|
560
|
+
```
|
561
|
+
|
562
|
+
Prints out:
|
563
|
+
|
564
|
+
```bash
|
565
|
+
[PD] /Users/User/example.rb:1
|
566
|
+
> pd (x=1), f: :t
|
567
|
+
=> "1"
|
568
|
+
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
530
569
|
```
|
531
570
|
|
532
571
|
Global Option Example:
|
@@ -543,11 +582,11 @@ Prints out:
|
|
543
582
|
[PD] /Users/User/example.rb:2
|
544
583
|
> pd (x=1)
|
545
584
|
=> "1"
|
546
|
-
|
585
|
+
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
547
586
|
[PD] /Users/User/example.rb:3
|
548
587
|
> pd (x=2)
|
549
588
|
=> "2"
|
550
|
-
|
589
|
+
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
551
590
|
```
|
552
591
|
|
553
592
|
#### `PutsDebuggerer.wrapper`
|
@@ -575,6 +614,22 @@ Prints out:
|
|
575
614
|
********************************************************************************
|
576
615
|
```
|
577
616
|
|
617
|
+
Shortcut Example:
|
618
|
+
|
619
|
+
```ruby
|
620
|
+
pd (x=1), w: :t
|
621
|
+
```
|
622
|
+
|
623
|
+
Prints out:
|
624
|
+
|
625
|
+
```bash
|
626
|
+
********************************************************************************
|
627
|
+
[PD] /Users/User/example.rb:1
|
628
|
+
> pd x=1, w: :t
|
629
|
+
=> "1"
|
630
|
+
********************************************************************************
|
631
|
+
```
|
632
|
+
|
578
633
|
Global Option Example:
|
579
634
|
|
580
635
|
```ruby
|
@@ -601,7 +656,7 @@ Prints out:
|
|
601
656
|
#### `PutsDebuggerer.source_line_count`
|
602
657
|
(default = `1`)
|
603
658
|
|
604
|
-
Prints multiple source code lines as per count specified. Useful when a statement is broken down on multiple lines or when there is a need to get more context around the line printed.
|
659
|
+
Prints multiple source code lines as per count specified. Useful when a statement is broken down on multiple lines or when there is a need to get more context around the line printed.
|
605
660
|
|
606
661
|
Example:
|
607
662
|
|
@@ -645,7 +700,7 @@ Examples of a global method are `:puts` and `:print`.
|
|
645
700
|
An example of a lambda expression is `lambda {|output| Rails.logger.info(output)}`
|
646
701
|
Examples of a logger are a Ruby `Logger` instance or `Logging::Logger` instance
|
647
702
|
|
648
|
-
When a logger is supplied, it is automatically enhanced with a PutsDebuggerer formatter to use
|
703
|
+
When a logger is supplied, it is automatically enhanced with a PutsDebuggerer formatter to use
|
649
704
|
when calling logger methods outside of PutsDebuggerer (e.g. `logger.error('msg')` will use `pd`)
|
650
705
|
|
651
706
|
Printer may be set to `false` to avoid printing and only return the formatted string.
|
@@ -951,16 +1006,29 @@ Prints out `puts __caller_source_line__`
|
|
951
1006
|
|
952
1007
|
## Compatibility
|
953
1008
|
|
954
|
-
[puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) is fully compatible with:
|
1009
|
+
[puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) is fully compatible with:
|
955
1010
|
- [Ruby](https://www.ruby-lang.org/en/)
|
956
1011
|
- [JRuby](https://www.jruby.org/)
|
957
|
-
- IRB
|
958
|
-
-
|
1012
|
+
- IRB (including Rails Console)
|
1013
|
+
- Pry
|
1014
|
+
|
1015
|
+
### Opal Ruby
|
1016
|
+
|
1017
|
+
[puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) provides partial-compatibility in [Opal Ruby](https://opalrb.com/) with everything working except:
|
1018
|
+
- AwesomePrint (using the `:p` printer instead)
|
1019
|
+
- Source code display
|
1020
|
+
|
1021
|
+
[puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) renders clickable source file/line links in Opal Ruby that take you to the source code in the web browser.
|
1022
|
+
|
1023
|
+
Here is an example of `pd` output in Opal:
|
1024
|
+
|
1025
|
+
```
|
1026
|
+
[PD] http://localhost:3000/assets/views/garderie_rainbow_daily_agenda/app_view.self-72626d75e0f68a619b1c8ad139535d799d45ab6c730d083820b790d71338e983.js?body=1:72:12
|
1027
|
+
>
|
1028
|
+
=> "body"
|
1029
|
+
```
|
959
1030
|
|
960
|
-
|
961
|
-
- File name display
|
962
|
-
- Line number display
|
963
|
-
- Source code call display
|
1031
|
+
Note that it ignores the configured printer when printing exceptions as it relies on Opal's `$stderr.puts` instead to show the stack trace in the web console.
|
964
1032
|
|
965
1033
|
## Change Log
|
966
1034
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.13.0
|
data/lib/puts_debuggerer.rb
CHANGED
@@ -1,24 +1,14 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
1
|
require 'puts_debuggerer/core_ext/kernel'
|
2
|
+
require 'puts_debuggerer/core_ext/logger'
|
3
|
+
require 'puts_debuggerer/core_ext/logging/logger'
|
4
4
|
require 'puts_debuggerer/run_determiner'
|
5
5
|
require 'puts_debuggerer/source_file'
|
6
6
|
|
7
|
-
# in case 'logger' is not required
|
8
|
-
class Logger
|
9
|
-
end
|
10
|
-
|
11
|
-
# in case 'logging' is not required
|
12
|
-
module Logging
|
13
|
-
class Logger
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
7
|
module PutsDebuggerer
|
18
8
|
SOURCE_LINE_COUNT_DEFAULT = 1
|
19
|
-
HEADER_DEFAULT = '
|
9
|
+
HEADER_DEFAULT = '>'*80
|
20
10
|
WRAPPER_DEFAULT = '*'*80
|
21
|
-
FOOTER_DEFAULT = '
|
11
|
+
FOOTER_DEFAULT = '<'*80
|
22
12
|
LOGGER_FORMATTER_DECORATOR = proc { |original_formatter|
|
23
13
|
proc { |severity, datetime, progname, msg|
|
24
14
|
original_formatter.call(severity, datetime, progname, msg.pd_inspect)
|
@@ -37,8 +27,12 @@ module PutsDebuggerer
|
|
37
27
|
RETURN_DEFAULT = true
|
38
28
|
OBJECT_PRINTER_DEFAULT = lambda do |object, print_engine_options=nil, source_line_count=nil, run_number=nil|
|
39
29
|
lambda do
|
40
|
-
if object.is_a?(Exception)
|
41
|
-
|
30
|
+
if object.is_a?(Exception)
|
31
|
+
if RUBY_ENGINE == 'opal'
|
32
|
+
object.backtrace.each { |line| puts line }
|
33
|
+
else
|
34
|
+
puts object.full_message
|
35
|
+
end
|
42
36
|
elsif PutsDebuggerer.print_engine.is_a?(Proc)
|
43
37
|
PutsDebuggerer.print_engine.call(object)
|
44
38
|
else
|
@@ -58,15 +52,23 @@ module PutsDebuggerer
|
|
58
52
|
FORMATTER_DEFAULT = -> (data) {
|
59
53
|
puts data[:wrapper] if data[:wrapper]
|
60
54
|
puts data[:header] if data[:header]
|
61
|
-
print "#{data[:announcer]} #{data[:file]}
|
55
|
+
print "#{data[:announcer]} #{data[:file]}#{':' if data[:line_number]}#{data[:line_number]}#{" (run:#{data[:run_number]})" if data[:run_number]}#{__format_pd_expression__(data[:pd_expression], data[:object])} "
|
62
56
|
data[:object_printer].call
|
63
57
|
puts data[:caller].map {|l| ' ' + l} unless data[:caller].to_a.empty?
|
64
58
|
puts data[:footer] if data[:footer]
|
65
59
|
puts data[:wrapper] if data[:wrapper]
|
66
60
|
}
|
67
61
|
CALLER_DEPTH_ZERO = 4 #depth includes pd + with_options method + nested block + build_pd_data method
|
62
|
+
CALLER_DEPTH_ZERO_OPAL = -1 #depth includes pd + with_options method + nested block + build_pd_data method
|
68
63
|
STACK_TRACE_CALL_LINE_NUMBER_REGEX = /\:(\d+)\:in /
|
69
64
|
STACK_TRACE_CALL_SOURCE_FILE_REGEX = /[ ]*([^:]+)\:\d+\:in /
|
65
|
+
STACK_TRACE_CALL_SOURCE_FILE_REGEX_OPAL = /(http[^\)]+)/
|
66
|
+
OPTIONS = [:app_path, :source_line_count, :header, :h, :wrapper, :w, :footer, :f, :printer, :print_engine, :announcer, :formatter, :caller, :run_at]
|
67
|
+
OPTION_ALIASES = {
|
68
|
+
h: :header,
|
69
|
+
f: :footer,
|
70
|
+
w: :wrapper
|
71
|
+
}
|
70
72
|
|
71
73
|
class << self
|
72
74
|
# Application root path to exclude when printing out file path
|
@@ -175,7 +177,7 @@ module PutsDebuggerer
|
|
175
177
|
instance_variable_set(:"@#{boundary_option}", nil)
|
176
178
|
else
|
177
179
|
instance_variable_set(:"@#{boundary_option}", value)
|
178
|
-
end
|
180
|
+
end
|
179
181
|
end
|
180
182
|
|
181
183
|
define_method("#{boundary_option}?") do
|
@@ -228,10 +230,10 @@ module PutsDebuggerer
|
|
228
230
|
end
|
229
231
|
|
230
232
|
def printer_default
|
231
|
-
Object.const_defined?(:Rails) ? PRINTER_RAILS : PRINTER_DEFAULT
|
233
|
+
Object.const_defined?(:Rails) ? PRINTER_RAILS : PRINTER_DEFAULT
|
232
234
|
end
|
233
235
|
|
234
|
-
# Logger original formatter before it was decorated with PutsDebuggerer::LOGGER_FORMATTER_DECORATOR
|
236
|
+
# Logger original formatter before it was decorated with PutsDebuggerer::LOGGER_FORMATTER_DECORATOR
|
235
237
|
# upon setting the logger as a printer.
|
236
238
|
attr_reader :logger_original_formatter
|
237
239
|
|
@@ -262,12 +264,16 @@ module PutsDebuggerer
|
|
262
264
|
# > pd array
|
263
265
|
# => [1, [2, 3]]
|
264
266
|
# ]
|
265
|
-
|
267
|
+
def print_engine
|
268
|
+
if @print_engine.nil?
|
269
|
+
require 'awesome_print' if RUBY_ENGINE != 'opal'
|
270
|
+
@print_engine = print_engine_default
|
271
|
+
end
|
272
|
+
@print_engine
|
273
|
+
end
|
266
274
|
|
267
275
|
def print_engine=(engine)
|
268
|
-
if engine.nil?
|
269
|
-
@print_engine = print_engine_default
|
270
|
-
elsif engine.is_a?(Proc)
|
276
|
+
if engine.is_a?(Proc) || engine.nil?
|
271
277
|
@print_engine = engine
|
272
278
|
else
|
273
279
|
@print_engine = method(engine).name rescue raise(PRINT_ENGINE_MESSAGE_INVALID)
|
@@ -275,7 +281,7 @@ module PutsDebuggerer
|
|
275
281
|
end
|
276
282
|
|
277
283
|
def print_engine_default
|
278
|
-
Object.const_defined?(:AwesomePrint) ? PRINT_ENGINE_DEFAULT : :p
|
284
|
+
Object.const_defined?(:AwesomePrint) ? PRINT_ENGINE_DEFAULT : :p
|
279
285
|
end
|
280
286
|
|
281
287
|
# Announcer (e.g. [PD]) to announce every print out with (default: "[PD]")
|
@@ -468,8 +474,19 @@ module PutsDebuggerer
|
|
468
474
|
!!@run_at
|
469
475
|
end
|
470
476
|
|
471
|
-
def determine_options(objects)
|
472
|
-
|
477
|
+
def determine_options(objects)
|
478
|
+
if objects.size > 1 && objects.last.is_a?(Hash)
|
479
|
+
convert_options(objects.delete_at(-1))
|
480
|
+
elsif objects.size == 1 && objects.first.is_a?(Hash)
|
481
|
+
hash = objects.first
|
482
|
+
convert_options(hash.slice(*OPTIONS).tap do
|
483
|
+
hash.delete_if {|option| OPTIONS.include?(option)}
|
484
|
+
end)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
def convert_options(hash)
|
489
|
+
Hash[hash.map { |key, value| OPTION_ALIASES[key] ? ( value == :t ? [OPTION_ALIASES[key], true] : [OPTION_ALIASES[key], value] ) : [key, value]}]
|
473
490
|
end
|
474
491
|
|
475
492
|
def determine_object(objects)
|
@@ -499,197 +516,3 @@ PutsDebuggerer.app_path = nil
|
|
499
516
|
PutsDebuggerer.caller = nil
|
500
517
|
PutsDebuggerer.run_at = nil
|
501
518
|
PutsDebuggerer.source_line_count = nil
|
502
|
-
|
503
|
-
# Prints object with bonus info such as file name, line number and source
|
504
|
-
# expression. Optionally prints out header and footer.
|
505
|
-
# Lookup PutsDebuggerer attributes for more details about configuration options.
|
506
|
-
#
|
507
|
-
# Simply invoke global `pd` method anywhere you'd like to see line number and source code with output.
|
508
|
-
# If the argument is a pure string, the print out is simplified by not showing duplicate source.
|
509
|
-
#
|
510
|
-
# Quickly locate printed lines using Find feature (e.g. CTRL+F) by looking for:
|
511
|
-
# * \[PD\]
|
512
|
-
# * file:line_number
|
513
|
-
# * ruby expression.
|
514
|
-
#
|
515
|
-
# This gives you the added benefit of easily removing your pd statements later on from the code.
|
516
|
-
#
|
517
|
-
# Happy puts_debuggerering!
|
518
|
-
#
|
519
|
-
# Example Code:
|
520
|
-
#
|
521
|
-
# # /Users/User/finance_calculator_app/pd_test.rb # line 1
|
522
|
-
# bug = 'beattle' # line 2
|
523
|
-
# pd "Show me the source of the bug: #{bug}" # line 3
|
524
|
-
# pd 'What line number am I?' # line 4
|
525
|
-
#
|
526
|
-
# Example Printout:
|
527
|
-
#
|
528
|
-
# [PD] /Users/User/finance_calculator_app/pd_test.rb:3
|
529
|
-
# > pd "Show me the source of the bug: #{bug}"
|
530
|
-
# => "Show me the source of the bug: beattle"
|
531
|
-
# [PD] /Users/User/finance_calculator_app/pd_test.rb:4 "What line number am I?"
|
532
|
-
def pd(*objects)
|
533
|
-
require 'awesome_print' if ['awesome_print', 'ap'].include?(PutsDebuggerer.print_engine.to_s) && RUBY_PLATFORM != 'opal'
|
534
|
-
options = PutsDebuggerer.determine_options(objects) || {}
|
535
|
-
object = PutsDebuggerer.determine_object(objects)
|
536
|
-
run_at = PutsDebuggerer.determine_run_at(options)
|
537
|
-
printer = PutsDebuggerer.determine_printer(options)
|
538
|
-
pd_inspect = options.delete(:pd_inspect)
|
539
|
-
logger_formatter_decorated = PutsDebuggerer.printer.is_a?(Logger) && PutsDebuggerer.printer.formatter != PutsDebuggerer.logger_original_formatter
|
540
|
-
logging_layouts_decorated = PutsDebuggerer.printer.is_a?(Logging::Logger) && PutsDebuggerer.printer.appenders.map(&:layout) != (PutsDebuggerer.logging_original_layouts.values)
|
541
|
-
|
542
|
-
string = nil
|
543
|
-
if PutsDebuggerer::RunDeterminer.run_pd?(object, run_at)
|
544
|
-
__with_pd_options__(options) do |print_engine_options|
|
545
|
-
run_number = PutsDebuggerer::RunDeterminer.run_number(object, run_at)
|
546
|
-
formatter_pd_data = __build_pd_data__(object, print_engine_options, PutsDebuggerer.source_line_count, run_number, pd_inspect, logger_formatter_decorated, logging_layouts_decorated) #depth adds build method
|
547
|
-
stdout = $stdout
|
548
|
-
$stdout = sio = StringIO.new
|
549
|
-
PutsDebuggerer.formatter.call(formatter_pd_data)
|
550
|
-
$stdout = stdout
|
551
|
-
string = sio.string
|
552
|
-
if PutsDebuggerer.printer.is_a?(Proc)
|
553
|
-
PutsDebuggerer.printer.call(string)
|
554
|
-
elsif PutsDebuggerer.printer.is_a?(Logger)
|
555
|
-
logger_formatter = PutsDebuggerer.printer.formatter
|
556
|
-
begin
|
557
|
-
PutsDebuggerer.printer.formatter = PutsDebuggerer.logger_original_formatter
|
558
|
-
PutsDebuggerer.printer.debug(string)
|
559
|
-
ensure
|
560
|
-
PutsDebuggerer.printer.formatter = logger_formatter
|
561
|
-
end
|
562
|
-
elsif PutsDebuggerer.printer.is_a?(Logging::Logger)
|
563
|
-
logging_layouts = PutsDebuggerer.printer.appenders.reduce({}) do |hash, appender|
|
564
|
-
hash.merge(appender => appender.layout)
|
565
|
-
end
|
566
|
-
begin
|
567
|
-
PutsDebuggerer.logging_original_layouts.each do |appender, original_layout|
|
568
|
-
appender.layout = original_layout
|
569
|
-
end
|
570
|
-
PutsDebuggerer.printer.debug(string)
|
571
|
-
ensure
|
572
|
-
PutsDebuggerer.logging_original_layouts.each do |appender, original_layout|
|
573
|
-
appender.layout = logging_layouts[appender]
|
574
|
-
end
|
575
|
-
end
|
576
|
-
elsif PutsDebuggerer.printer != false
|
577
|
-
send(PutsDebuggerer.send(:printer), string)
|
578
|
-
end
|
579
|
-
end
|
580
|
-
end
|
581
|
-
|
582
|
-
printer ? object : string
|
583
|
-
end
|
584
|
-
|
585
|
-
# Provides caller line number starting 1 level above caller of
|
586
|
-
# this method.
|
587
|
-
#
|
588
|
-
# Example:
|
589
|
-
#
|
590
|
-
# # lib/example.rb # line 1
|
591
|
-
# puts "Print out __caller_line_number__" # line 2
|
592
|
-
# puts __caller_line_number__ # line 3
|
593
|
-
#
|
594
|
-
# prints out `3`
|
595
|
-
def __caller_line_number__(caller_depth=0)
|
596
|
-
caller[caller_depth] && caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_LINE_NUMBER_REGEX, 1].to_i
|
597
|
-
end
|
598
|
-
|
599
|
-
# Provides caller file starting 1 level above caller of
|
600
|
-
# this method.
|
601
|
-
#
|
602
|
-
# Example:
|
603
|
-
#
|
604
|
-
# # File Name: lib/example.rb
|
605
|
-
# puts __caller_file__
|
606
|
-
#
|
607
|
-
# prints out `lib/example.rb`
|
608
|
-
def __caller_file__(caller_depth=0)
|
609
|
-
result = caller[caller_depth] && caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_SOURCE_FILE_REGEX, 1]
|
610
|
-
end
|
611
|
-
|
612
|
-
|
613
|
-
# Provides caller source line starting 1 level above caller of
|
614
|
-
# this method.
|
615
|
-
#
|
616
|
-
# Example:
|
617
|
-
#
|
618
|
-
# puts __caller_source_line__
|
619
|
-
#
|
620
|
-
# prints out `puts __caller_source_line__`
|
621
|
-
def __caller_source_line__(caller_depth=0, source_line_count=nil, source_file=nil, source_line_number=nil)
|
622
|
-
source_line_number ||= __caller_line_number__(caller_depth+1)
|
623
|
-
source_file ||= __caller_file__(caller_depth+1)
|
624
|
-
source_line = ''
|
625
|
-
if source_file == '(irb)'
|
626
|
-
source_line = conf.io.line(source_line_number) # TODO handle multi-lines in source_line_count
|
627
|
-
else
|
628
|
-
source_line = PutsDebuggerer::SourceFile.new(source_file).source(source_line_count, source_line_number)
|
629
|
-
end
|
630
|
-
source_line
|
631
|
-
end
|
632
|
-
|
633
|
-
private
|
634
|
-
|
635
|
-
def __with_pd_options__(options=nil)
|
636
|
-
options ||= {}
|
637
|
-
permanent_options = PutsDebuggerer.options
|
638
|
-
PutsDebuggerer.options = options.select {|option, _| PutsDebuggerer.options.keys.include?(option)}
|
639
|
-
print_engine_options = options.delete_if {|option, _| PutsDebuggerer.options.keys.include?(option)}
|
640
|
-
yield print_engine_options
|
641
|
-
PutsDebuggerer.options = permanent_options
|
642
|
-
end
|
643
|
-
|
644
|
-
def __build_pd_data__(object, print_engine_options=nil, source_line_count=nil, run_number=nil, pd_inspect=false, logger_formatter_decorated=false, logging_layouts_decorated=false)
|
645
|
-
depth = PutsDebuggerer::CALLER_DEPTH_ZERO
|
646
|
-
depth += 1 if pd_inspect
|
647
|
-
depth += 4 if pd_inspect && logger_formatter_decorated
|
648
|
-
depth += 8 if pd_inspect && logging_layouts_decorated
|
649
|
-
pd_data = {
|
650
|
-
announcer: PutsDebuggerer.announcer,
|
651
|
-
file: __caller_file__(depth)&.sub(PutsDebuggerer.app_path.to_s, ''),
|
652
|
-
line_number: __caller_line_number__(depth),
|
653
|
-
pd_expression: __caller_pd_expression__(depth, source_line_count),
|
654
|
-
run_number: run_number,
|
655
|
-
object: object,
|
656
|
-
object_printer: PutsDebuggerer::OBJECT_PRINTER_DEFAULT.call(object, print_engine_options, source_line_count, run_number)
|
657
|
-
}
|
658
|
-
pd_data[:caller] = __caller_caller__(depth)
|
659
|
-
['header', 'wrapper', 'footer'].each do |boundary_option|
|
660
|
-
pd_data[boundary_option.to_sym] = PutsDebuggerer.send(boundary_option) if PutsDebuggerer.send("#{boundary_option}?")
|
661
|
-
end
|
662
|
-
pd_data
|
663
|
-
end
|
664
|
-
|
665
|
-
# Returns the caller stack trace of the caller of pd
|
666
|
-
def __caller_caller__(depth)
|
667
|
-
return unless PutsDebuggerer.caller?
|
668
|
-
start_depth = depth.to_i + 1
|
669
|
-
caller_depth = PutsDebuggerer.caller == -1 ? -1 : (start_depth + PutsDebuggerer.caller)
|
670
|
-
caller[start_depth..caller_depth].to_a
|
671
|
-
end
|
672
|
-
|
673
|
-
def __format_pd_expression__(expression, object)
|
674
|
-
"\n > #{expression}\n =>"
|
675
|
-
end
|
676
|
-
|
677
|
-
def __caller_pd_expression__(depth=0, source_line_count=nil)
|
678
|
-
# Caller Source Line Depth 2 = 1 to pd method + 1 to caller
|
679
|
-
source_line = __caller_source_line__(depth+1, source_line_count)
|
680
|
-
source_line = __extract_pd_expression__(source_line)
|
681
|
-
source_line = source_line.gsub(/(^'|'$)/, '"') if source_line.start_with?("'") && source_line.end_with?("'")
|
682
|
-
source_line = source_line.gsub(/(^\(|\)$)/, '') if source_line.start_with?("(") && source_line.end_with?(")")
|
683
|
-
source_line
|
684
|
-
end
|
685
|
-
|
686
|
-
# Extracts pd source line expression.
|
687
|
-
#
|
688
|
-
# Example:
|
689
|
-
#
|
690
|
-
# __extract_pd_expression__("pd (x=1)")
|
691
|
-
#
|
692
|
-
# outputs `(x=1)`
|
693
|
-
def __extract_pd_expression__(source_line)
|
694
|
-
source_line.to_s.strip
|
695
|
-
end
|
@@ -1,6 +1,224 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
1
3
|
module Kernel
|
4
|
+
# Prints object with bonus info such as file name, line number and source
|
5
|
+
# expression. Optionally prints out header and footer.
|
6
|
+
# Lookup PutsDebuggerer attributes for more details about configuration options.
|
7
|
+
#
|
8
|
+
# Simply invoke global `pd` method anywhere you'd like to see line number and source code with output.
|
9
|
+
# If the argument is a pure string, the print out is simplified by not showing duplicate source.
|
10
|
+
#
|
11
|
+
# Quickly locate printed lines using Find feature (e.g. CTRL+F) by looking for:
|
12
|
+
# * \[PD\]
|
13
|
+
# * file:line_number
|
14
|
+
# * ruby expression.
|
15
|
+
#
|
16
|
+
# This gives you the added benefit of easily removing your pd statements later on from the code.
|
17
|
+
#
|
18
|
+
# Happy puts_debuggerering!
|
19
|
+
#
|
20
|
+
# Example Code:
|
21
|
+
#
|
22
|
+
# # /Users/User/finance_calculator_app/pd_test.rb # line 1
|
23
|
+
# bug = 'beattle' # line 2
|
24
|
+
# pd "Show me the source of the bug: #{bug}" # line 3
|
25
|
+
# pd 'What line number am I?' # line 4
|
26
|
+
#
|
27
|
+
# Example Printout:
|
28
|
+
#
|
29
|
+
# [PD] /Users/User/finance_calculator_app/pd_test.rb:3
|
30
|
+
# > pd "Show me the source of the bug: #{bug}"
|
31
|
+
# => "Show me the source of the bug: beattle"
|
32
|
+
# [PD] /Users/User/finance_calculator_app/pd_test.rb:4 "What line number am I?"
|
33
|
+
def pd(*objects)
|
34
|
+
options = PutsDebuggerer.determine_options(objects) || {}
|
35
|
+
object = PutsDebuggerer.determine_object(objects)
|
36
|
+
run_at = PutsDebuggerer.determine_run_at(options)
|
37
|
+
printer = PutsDebuggerer.determine_printer(options)
|
38
|
+
pd_inspect = options.delete(:pd_inspect)
|
39
|
+
logger_formatter_decorated = PutsDebuggerer.printer.is_a?(Logger) && PutsDebuggerer.printer.formatter != PutsDebuggerer.logger_original_formatter
|
40
|
+
logging_layouts_decorated = PutsDebuggerer.printer.is_a?(Logging::Logger) && PutsDebuggerer.printer.appenders.map(&:layout) != (PutsDebuggerer.logging_original_layouts.values)
|
41
|
+
|
42
|
+
string = nil
|
43
|
+
if PutsDebuggerer::RunDeterminer.run_pd?(object, run_at)
|
44
|
+
__with_pd_options__(options) do |print_engine_options|
|
45
|
+
run_number = PutsDebuggerer::RunDeterminer.run_number(object, run_at)
|
46
|
+
formatter_pd_data = __build_pd_data__(object, print_engine_options: print_engine_options, source_line_count: PutsDebuggerer.source_line_count, run_number: run_number, pd_inspect: pd_inspect, logger_formatter_decorated: logger_formatter_decorated, logging_layouts_decorated: logging_layouts_decorated)
|
47
|
+
stdout = $stdout
|
48
|
+
$stdout = sio = StringIO.new
|
49
|
+
PutsDebuggerer.formatter.call(formatter_pd_data)
|
50
|
+
$stdout = stdout
|
51
|
+
string = sio.string
|
52
|
+
if RUBY_ENGINE == 'opal' && object.is_a?(Exception)
|
53
|
+
$stderr.puts(string)
|
54
|
+
else
|
55
|
+
if PutsDebuggerer.printer.is_a?(Proc)
|
56
|
+
PutsDebuggerer.printer.call(string)
|
57
|
+
elsif PutsDebuggerer.printer.is_a?(Logger)
|
58
|
+
logger_formatter = PutsDebuggerer.printer.formatter
|
59
|
+
begin
|
60
|
+
PutsDebuggerer.printer.formatter = PutsDebuggerer.logger_original_formatter
|
61
|
+
PutsDebuggerer.printer.debug(string)
|
62
|
+
ensure
|
63
|
+
PutsDebuggerer.printer.formatter = logger_formatter
|
64
|
+
end
|
65
|
+
elsif PutsDebuggerer.printer.is_a?(Logging::Logger)
|
66
|
+
logging_layouts = PutsDebuggerer.printer.appenders.reduce({}) do |hash, appender|
|
67
|
+
hash.merge(appender => appender.layout)
|
68
|
+
end
|
69
|
+
begin
|
70
|
+
PutsDebuggerer.logging_original_layouts.each do |appender, original_layout|
|
71
|
+
appender.layout = original_layout
|
72
|
+
end
|
73
|
+
PutsDebuggerer.printer.debug(string)
|
74
|
+
ensure
|
75
|
+
PutsDebuggerer.logging_original_layouts.each do |appender, original_layout|
|
76
|
+
appender.layout = logging_layouts[appender]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
elsif PutsDebuggerer.printer != false
|
80
|
+
send(PutsDebuggerer.send(:printer), string)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
printer ? object : string
|
87
|
+
end
|
88
|
+
|
89
|
+
# Implement caller backtrace method in Opal since it returns an empty array in Opal v1
|
90
|
+
if RUBY_ENGINE == 'opal'
|
91
|
+
def caller
|
92
|
+
begin
|
93
|
+
raise 'error'
|
94
|
+
rescue => e
|
95
|
+
e.backtrace[2..-1]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
2
100
|
def pd_inspect
|
3
101
|
pd self, printer: false, pd_inspect: true
|
4
102
|
end
|
5
103
|
alias pdi pd_inspect
|
104
|
+
|
105
|
+
# Provides caller line number starting 1 level above caller of
|
106
|
+
# this method.
|
107
|
+
#
|
108
|
+
# Example:
|
109
|
+
#
|
110
|
+
# # lib/example.rb # line 1
|
111
|
+
# puts "Print out __caller_line_number__" # line 2
|
112
|
+
# puts __caller_line_number__ # line 3
|
113
|
+
#
|
114
|
+
# prints out `3`
|
115
|
+
def __caller_line_number__(caller_depth=0)
|
116
|
+
return if RUBY_ENGINE == 'opal'
|
117
|
+
caller[caller_depth] && caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_LINE_NUMBER_REGEX, 1].to_i
|
118
|
+
end
|
119
|
+
|
120
|
+
# Provides caller file starting 1 level above caller of
|
121
|
+
# this method.
|
122
|
+
#
|
123
|
+
# Example:
|
124
|
+
#
|
125
|
+
# # File Name: lib/example.rb
|
126
|
+
# puts __caller_file__
|
127
|
+
#
|
128
|
+
# prints out `lib/example.rb`
|
129
|
+
def __caller_file__(caller_depth=0)
|
130
|
+
regex = RUBY_ENGINE == 'opal' ? PutsDebuggerer::STACK_TRACE_CALL_SOURCE_FILE_REGEX_OPAL : PutsDebuggerer::STACK_TRACE_CALL_SOURCE_FILE_REGEX
|
131
|
+
caller[caller_depth] && caller[caller_depth][regex, 1]
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
# Provides caller source line starting 1 level above caller of
|
136
|
+
# this method.
|
137
|
+
#
|
138
|
+
# Example:
|
139
|
+
#
|
140
|
+
# puts __caller_source_line__
|
141
|
+
#
|
142
|
+
# prints out `puts __caller_source_line__`
|
143
|
+
def __caller_source_line__(caller_depth=0, source_line_count=nil, source_file=nil, source_line_number=nil)
|
144
|
+
source_line_number ||= __caller_line_number__(caller_depth+1)
|
145
|
+
source_file ||= __caller_file__(caller_depth+1)
|
146
|
+
source_line = ''
|
147
|
+
if defined?(Pry)
|
148
|
+
@pry_instance ||= Pry.new
|
149
|
+
source_line = Pry::Command::Hist.new(pry_instance: @pry_instance).call.instance_variable_get(:@buffer).split("\n")[source_line_number - 1] # TODO handle multi-lines in source_line_count
|
150
|
+
elsif defined?(IRB)
|
151
|
+
source_line = TOPLEVEL_BINDING.receiver.conf.io.line(source_line_number) # TODO handle multi-lines in source_line_count
|
152
|
+
else
|
153
|
+
source_line = PutsDebuggerer::SourceFile.new(source_file).source(source_line_count, source_line_number)
|
154
|
+
end
|
155
|
+
source_line
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def __with_pd_options__(options=nil)
|
161
|
+
options ||= {}
|
162
|
+
permanent_options = PutsDebuggerer.options
|
163
|
+
PutsDebuggerer.options = options.select {|option, _| PutsDebuggerer.options.keys.include?(option)}
|
164
|
+
print_engine_options = options.delete_if {|option, _| PutsDebuggerer.options.keys.include?(option)}
|
165
|
+
yield print_engine_options
|
166
|
+
PutsDebuggerer.options = permanent_options
|
167
|
+
end
|
168
|
+
|
169
|
+
def __build_pd_data__(object, print_engine_options:nil, source_line_count:nil, run_number:nil, pd_inspect:false, logger_formatter_decorated:false, logging_layouts_decorated:false)
|
170
|
+
depth = RUBY_ENGINE == 'opal' ? PutsDebuggerer::CALLER_DEPTH_ZERO_OPAL : PutsDebuggerer::CALLER_DEPTH_ZERO
|
171
|
+
if pd_inspect
|
172
|
+
depth += 1
|
173
|
+
depth += 4 if logger_formatter_decorated
|
174
|
+
depth += 8 if logging_layouts_decorated
|
175
|
+
end
|
176
|
+
|
177
|
+
pd_data = {
|
178
|
+
announcer: PutsDebuggerer.announcer,
|
179
|
+
file: __caller_file__(depth)&.sub(PutsDebuggerer.app_path.to_s, ''),
|
180
|
+
line_number: __caller_line_number__(depth),
|
181
|
+
pd_expression: __caller_pd_expression__(depth, source_line_count),
|
182
|
+
run_number: run_number,
|
183
|
+
object: object,
|
184
|
+
object_printer: PutsDebuggerer::OBJECT_PRINTER_DEFAULT.call(object, print_engine_options, source_line_count, run_number)
|
185
|
+
}
|
186
|
+
pd_data[:caller] = __caller_caller__(depth)
|
187
|
+
['header', 'wrapper', 'footer'].each do |boundary_option|
|
188
|
+
pd_data[boundary_option.to_sym] = PutsDebuggerer.send(boundary_option) if PutsDebuggerer.send("#{boundary_option}?")
|
189
|
+
end
|
190
|
+
pd_data
|
191
|
+
end
|
192
|
+
|
193
|
+
# Returns the caller stack trace of the caller of pd
|
194
|
+
def __caller_caller__(depth)
|
195
|
+
return unless PutsDebuggerer.caller?
|
196
|
+
start_depth = depth.to_i + 1
|
197
|
+
caller_depth = PutsDebuggerer.caller == -1 ? -1 : (start_depth + PutsDebuggerer.caller)
|
198
|
+
caller[start_depth..caller_depth].to_a
|
199
|
+
end
|
200
|
+
|
201
|
+
def __format_pd_expression__(expression, object)
|
202
|
+
"\n > #{expression}\n =>"
|
203
|
+
end
|
204
|
+
|
205
|
+
def __caller_pd_expression__(depth=0, source_line_count=nil)
|
206
|
+
# Caller Source Line Depth 2 = 1 to pd method + 1 to caller
|
207
|
+
source_line = __caller_source_line__(depth+1, source_line_count)
|
208
|
+
source_line = __extract_pd_expression__(source_line)
|
209
|
+
source_line = source_line.gsub(/(^'|'$)/, '"') if source_line.start_with?("'") && source_line.end_with?("'")
|
210
|
+
source_line = source_line.gsub(/(^\(|\)$)/, '') if source_line.start_with?("(") && source_line.end_with?(")")
|
211
|
+
source_line
|
212
|
+
end
|
213
|
+
|
214
|
+
# Extracts pd source line expression.
|
215
|
+
#
|
216
|
+
# Example:
|
217
|
+
#
|
218
|
+
# __extract_pd_expression__("pd (x=1)")
|
219
|
+
#
|
220
|
+
# outputs `(x=1)`
|
221
|
+
def __extract_pd_expression__(source_line)
|
222
|
+
source_line.to_s.strip
|
223
|
+
end
|
6
224
|
end
|
@@ -42,19 +42,19 @@ module PutsDebuggerer
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def run_number(object, run_at)
|
45
|
-
run_at_global_number || run_at_number(object, run_at)
|
46
|
-
end
|
45
|
+
run_at_global_number || run_at_number(object, run_at)
|
46
|
+
end
|
47
47
|
|
48
48
|
def run_pd?(object, run_at)
|
49
49
|
run_pd = false
|
50
50
|
if run_at.nil?
|
51
51
|
run_pd = true
|
52
52
|
else
|
53
|
-
run_number = determine_run_number(object, run_at)
|
53
|
+
run_number = determine_run_number(object, run_at)
|
54
54
|
run_pd = determine_run_pd(run_at, run_number)
|
55
55
|
end
|
56
56
|
run_pd
|
57
|
-
end
|
57
|
+
end
|
58
58
|
|
59
59
|
def determine_run_number(object, run_at)
|
60
60
|
if PutsDebuggerer.run_at? # check if global option is set
|
@@ -70,7 +70,7 @@ module PutsDebuggerer
|
|
70
70
|
else
|
71
71
|
PutsDebuggerer::RunDeterminer.increment_run_at_global_number
|
72
72
|
end
|
73
|
-
PutsDebuggerer::RunDeterminer.run_at_global_number
|
73
|
+
PutsDebuggerer::RunDeterminer.run_at_global_number
|
74
74
|
end
|
75
75
|
|
76
76
|
def determine_local_run_number(object, run_at)
|
@@ -89,11 +89,11 @@ module PutsDebuggerer
|
|
89
89
|
determine_run_pd_array(run_at, run_number)
|
90
90
|
elsif run_at.is_a?(Range)
|
91
91
|
determine_run_pd_range(run_at, run_number)
|
92
|
-
end
|
92
|
+
end
|
93
93
|
end
|
94
94
|
|
95
95
|
def determine_run_pd_integer(run_at, run_number)
|
96
|
-
run_pd = true if run_at == run_number
|
96
|
+
run_pd = true if run_at == run_number
|
97
97
|
end
|
98
98
|
|
99
99
|
def determine_run_pd_array(run_at, run_number)
|
@@ -1,15 +1,16 @@
|
|
1
1
|
module PutsDebuggerer
|
2
|
-
class SourceFile
|
2
|
+
class SourceFile
|
3
3
|
def initialize(file_path)
|
4
|
-
@file = File.new(file_path)
|
4
|
+
@file = File.new(file_path) if file_path
|
5
5
|
end
|
6
6
|
|
7
7
|
def source(source_line_count, source_line_number)
|
8
8
|
@source = ''
|
9
|
+
return @source if RUBY_ENGINE == 'opal'
|
9
10
|
# For Opal Ruby compatibility, skip source lines if file does not respond to readline (as in Opal)
|
10
11
|
lines = source_lines(source_line_count, source_line_number)
|
11
12
|
@source = lines.join(' '*5) if @file.respond_to?(:readline)
|
12
|
-
@source
|
13
|
+
@source
|
13
14
|
end
|
14
15
|
|
15
16
|
def source_lines(source_line_count, source_line_number)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puts_debuggerer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_print
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.9.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.9.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,14 +84,14 @@ dependencies:
|
|
84
84
|
name: bundler
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 2.1.4
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 2.1.4
|
97
97
|
- !ruby/object:Gem::Dependency
|
@@ -137,33 +137,33 @@ dependencies:
|
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: 0.7.0
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: logging
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: 2.3.0
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: 2.3.0
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: rake-tui
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
159
|
+
version: '0'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version:
|
166
|
+
version: '0'
|
167
167
|
description: |
|
168
168
|
Debuggers are great! They help us troubleshoot complicated programming problems by inspecting values produced by code, line by line. They are invaluable when trying to understand what is going on in a large application composed of thousands or millions of lines of code.
|
169
169
|
In day-to-day test-driven development and simple debugging though, a puts statement can be a lot quicker in revealing what is going on than halting execution completely just to inspect a single value or a few. This is certainly true when writing the simplest possible code that could possibly work, and running a test every few seconds or minutes. Problem is you need to locate puts statements in large output logs, know which methods were invoked, find out what variable names are being printed, and see nicely formatted output. Enter puts_debuggerer. A guilt-free puts debugging Ruby gem FTW that prints file names, line numbers, code statements, and formats output nicely courtesy of awesome_print.
|
@@ -183,6 +183,8 @@ files:
|
|
183
183
|
- lib/pd.rb
|
184
184
|
- lib/puts_debuggerer.rb
|
185
185
|
- lib/puts_debuggerer/core_ext/kernel.rb
|
186
|
+
- lib/puts_debuggerer/core_ext/logger.rb
|
187
|
+
- lib/puts_debuggerer/core_ext/logging/logger.rb
|
186
188
|
- lib/puts_debuggerer/run_determiner.rb
|
187
189
|
- lib/puts_debuggerer/source_file.rb
|
188
190
|
homepage: http://github.com/AndyObtiva/puts_debuggerer
|
@@ -204,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
206
|
- !ruby/object:Gem::Version
|
205
207
|
version: '0'
|
206
208
|
requirements: []
|
207
|
-
rubygems_version: 3.
|
209
|
+
rubygems_version: 3.2.22
|
208
210
|
signing_key:
|
209
211
|
specification_version: 4
|
210
212
|
summary: Ruby library for improved puts debugging, automatically displaying bonus
|