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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b97ba980916a6d84faa8817ed75f1cc5d19841435e707a61090c5bfaf511872e
4
- data.tar.gz: 05e9a62ad2893e1394e18359652f5de012536b90f61ba6a2507501daaf73b774
3
+ metadata.gz: 9dcb8700ea76c5b172428f7a4c08285244da367442f8a5bb90b45d1c25f7b107
4
+ data.tar.gz: ee730414f3252a164a5ff1d0f4321564dc9c11e36e72f7e2f63998128dbf2c1a
5
5
  SHA512:
6
- metadata.gz: 397639f53099e9fa91b5cbc7a42b0fe7c465eb2835e6b08307c5ae0b0e01036f6d3ee428c204375f2a5c977543715955f3efbd448bceb4dde59bea21f9a09290
7
- data.tar.gz: b53f8db42dea2a575f438357e43966a478692cb73342dbc9255ed7e23196758f2e166180e26283bd06f19974a2a570e2bc01f52f5d37f27d57b939e16e40e797
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 'puts_debuggerer' # line 2
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 '*'*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.
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 powerful features in [puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) as detailed below.
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.10.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.10.0
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
- You may disable when needed by not requiring in Ruby or by adding an explicit reference to awesome_print with `require: false` in bundler:
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
- #### Ruby Logger and Logging::Logger
388
+ #### `pd_inspect` kernel method
390
389
 
391
- Ruby Logger and Logging::Logger (from [logging gem](https://github.com/TwP/logging)) are supported as [printers](#putsdebuggererprinter) (learn more under [PutsDebuggerer#printer](#putsdebuggererprinter)).
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 = `'*'*80`)
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 `'*'*80`
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 = `'*'*80`)
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 `'*'*80`
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
- - Rails Console.
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
- It provides partial-compatibility for [Opal Ruby](https://opalrb.com/), with everything working except these features:
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.10.0
1
+ 0.13.0
@@ -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 = '*'*80
9
+ HEADER_DEFAULT = '>'*80
20
10
  WRAPPER_DEFAULT = '*'*80
21
- FOOTER_DEFAULT = '*'*80
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) && object.respond_to?(:full_message)
41
- puts object.full_message
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]}:#{data[:line_number]}#{" (run:#{data[:run_number]})" if data[:run_number]}#{__format_pd_expression__(data[:pd_expression], data[:object])} "
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
- attr_reader :print_engine
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
- objects.delete_at(-1) if objects.size > 1 && objects.last.is_a?(Hash)
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
@@ -0,0 +1,3 @@
1
+ # in case 'logger' is not required
2
+ class Logger
3
+ end
@@ -0,0 +1,5 @@
1
+ # in case 'logging' is not required
2
+ module Logging
3
+ class Logger
4
+ end
5
+ 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.10.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: 2020-08-26 00:00:00.000000000 Z
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.8.0
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.8.0
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: undercover
140
+ name: logging
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
143
+ - - ">="
144
144
  - !ruby/object:Gem::Version
145
- version: 0.3.4
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: 0.3.4
152
+ version: 2.3.0
153
153
  - !ruby/object:Gem::Dependency
154
- name: logging
154
+ name: rake-tui
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: 2.3.0
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: 2.3.0
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.1.4
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