puts_debuggerer 0.9.0 → 0.10.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 +10 -0
- data/README.md +304 -25
- data/VERSION +1 -1
- data/lib/pd.rb +1 -0
- data/lib/puts_debuggerer.rb +160 -163
- data/lib/puts_debuggerer/core_ext/kernel.rb +6 -0
- data/lib/puts_debuggerer/run_determiner.rb +109 -0
- data/lib/puts_debuggerer/source_file.rb +31 -0
- metadata +21 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b97ba980916a6d84faa8817ed75f1cc5d19841435e707a61090c5bfaf511872e
|
4
|
+
data.tar.gz: 05e9a62ad2893e1394e18359652f5de012536b90f61ba6a2507501daaf73b774
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 397639f53099e9fa91b5cbc7a42b0fe7c465eb2835e6b08307c5ae0b0e01036f6d3ee428c204375f2a5c977543715955f3efbd448bceb4dde59bea21f9a09290
|
7
|
+
data.tar.gz: b53f8db42dea2a575f438357e43966a478692cb73342dbc9255ed7e23196758f2e166180e26283bd06f19974a2a570e2bc01f52f5d37f27d57b939e16e40e797
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.10.0
|
4
|
+
|
5
|
+
- Support `require 'pd`' as a shorter alternative to `require 'puts_debuggerer'`
|
6
|
+
- Support `printer` as a Logger object or Logging::Logger (from "logging" gem). Basically any object that responds to :debug method.
|
7
|
+
- Support `printer: false` option to return rendered String instead of printing and returning object
|
8
|
+
- Set logger formatter to PutsDebuggerer::LOGGER_FORMATTER_DECORATOR when passing as printer (keeping format the same, but decorating msg with pd)
|
9
|
+
- Add pd_inspect (and pdi alias) Kernel core extension methods
|
10
|
+
- Made awesome_print gem require happen only if printer is set to :ap or :awesome_print
|
11
|
+
- Support logging gem logger and Decorate logger layout with PutsDebuggerer::LOGGING_LAYOUT_DECORATOR for logging gem
|
12
|
+
|
3
13
|
## 0.9.0
|
4
14
|
|
5
15
|
- Provide partial support for Opal Ruby (missing display of file name, line number, and source code)
|
data/README.md
CHANGED
@@ -2,10 +2,17 @@
|
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/puts_debuggerer.svg)](http://badge.fury.io/rb/puts_debuggerer)
|
3
3
|
[![Build Status](https://travis-ci.org/AndyObtiva/puts_debuggerer.svg?branch=master)](https://travis-ci.org/AndyObtiva/puts_debuggerer)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/puts_debuggerer/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/puts_debuggerer?branch=master)
|
5
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/81d8f6e046eb1b4a36f4/maintainability)](https://codeclimate.com/github/AndyObtiva/puts_debuggerer/maintainability)
|
6
|
+
|
7
|
+
(credit to Aaron Patterson for partial inspiration: https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html)
|
5
8
|
|
6
9
|
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.
|
7
10
|
|
8
|
-
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.
|
11
|
+
In day-to-day test-driven development and simple app 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. Still, there are a number of problems with puts debugging, like difficulty in locating puts statements in a large output log, knowing which methods and line numbers were invoked, identifying which variables were printed, and seeing the content of structured hashes and arrays in an understandable format.
|
12
|
+
|
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
|
+
|
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.
|
9
16
|
|
10
17
|
Basic Example:
|
11
18
|
|
@@ -19,17 +26,14 @@ pd bug_or_band # line 4
|
|
19
26
|
Output:
|
20
27
|
|
21
28
|
```bash
|
22
|
-
[PD] trivia_app.rb:4
|
29
|
+
[PD] /Users/User/trivia_app.rb:4
|
23
30
|
> pd bug_or_band # line 4
|
24
31
|
=> "beattle"
|
25
32
|
```
|
26
33
|
|
27
34
|
## Background
|
28
35
|
|
29
|
-
|
30
|
-
https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html
|
31
|
-
|
32
|
-
It can be quite frustrating to lose puts statements in a large output or log file. One way to help find them is add a header (e.g. `puts "The Order Total"`) or an announcer (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.
|
33
37
|
|
34
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.
|
35
39
|
|
@@ -80,7 +84,7 @@ puts "order_details"
|
|
80
84
|
puts order_details
|
81
85
|
```
|
82
86
|
|
83
|
-
Here is a simple example using `pd` instead:
|
87
|
+
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:
|
84
88
|
|
85
89
|
```ruby
|
86
90
|
pd order_total
|
@@ -94,7 +98,15 @@ Output:
|
|
94
98
|
=> 195.50
|
95
99
|
```
|
96
100
|
|
97
|
-
This is not only easy to locate in a logging stream such as the one below, but also
|
101
|
+
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):
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
pd order_total
|
105
|
+
pd order_summary
|
106
|
+
pd order_details
|
107
|
+
```
|
108
|
+
|
109
|
+
Output:
|
98
110
|
|
99
111
|
```
|
100
112
|
(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)
|
@@ -105,24 +117,184 @@ This is not only easy to locate in a logging stream such as the one below, but a
|
|
105
117
|
(0.2ms) BEGIN
|
106
118
|
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]]
|
107
119
|
(0.3ms) COMMIT
|
108
|
-
[PD] /Users/User/ordering/order.rb:
|
109
|
-
> pd
|
110
|
-
=>
|
120
|
+
[PD] /Users/User/ordering/order.rb:40
|
121
|
+
> pd order_summary
|
122
|
+
=> "Pragmatic Ruby Book"
|
111
123
|
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]]
|
112
124
|
(0.2ms) BEGIN
|
113
125
|
(0.2ms) COMMIT
|
126
|
+
[PD] /Users/User/ordering/order.rb:41
|
127
|
+
> pd order_details
|
128
|
+
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
129
|
+
```
|
130
|
+
|
131
|
+
What if you would like to add a header for faster findability? Just use the `header` option:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
pd order_total, header: true
|
135
|
+
pd order_summary
|
136
|
+
pd order_details
|
114
137
|
```
|
115
138
|
|
116
|
-
|
139
|
+
Output:
|
140
|
+
|
141
|
+
```
|
142
|
+
(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
|
+
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
|
+
********************************************************************************
|
145
|
+
[PD] /Users/User/ordering/order.rb:39
|
146
|
+
> pd order_total, header: true
|
147
|
+
=> 195.50
|
148
|
+
(0.2ms) BEGIN
|
149
|
+
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
|
+
(0.3ms) COMMIT
|
151
|
+
[PD] /Users/User/ordering/order.rb:40
|
152
|
+
> pd order_summary
|
153
|
+
=> "Pragmatic Ruby Book"
|
154
|
+
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
|
+
(0.2ms) BEGIN
|
156
|
+
(0.2ms) COMMIT
|
157
|
+
[PD] /Users/User/ordering/order.rb:41
|
158
|
+
> pd order_details
|
159
|
+
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
160
|
+
```
|
117
161
|
|
118
|
-
|
162
|
+
Wanna customize the header and add a footer too? No problem:
|
119
163
|
|
120
164
|
```ruby
|
121
|
-
pd order_total
|
165
|
+
pd order_total, header: '>'*80
|
166
|
+
pd order_summary
|
167
|
+
pd order_details, footer: '<'*80
|
168
|
+
```
|
169
|
+
|
170
|
+
Output:
|
171
|
+
|
172
|
+
```
|
173
|
+
(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)
|
174
|
+
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]]
|
175
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
176
|
+
[PD] /Users/User/ordering/order.rb:39
|
177
|
+
> pd order_total, header: '>'*80
|
178
|
+
=> 195.50
|
179
|
+
(0.2ms) BEGIN
|
180
|
+
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
|
+
(0.3ms) COMMIT
|
182
|
+
[PD] /Users/User/ordering/order.rb:40
|
183
|
+
> pd order_summary
|
184
|
+
=> "Pragmatic Ruby Book"
|
185
|
+
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
|
+
(0.2ms) BEGIN
|
187
|
+
(0.2ms) COMMIT
|
188
|
+
[PD] /Users/User/ordering/order.rb:41
|
189
|
+
> pd order_details, footer: '<'*80
|
190
|
+
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
191
|
+
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
192
|
+
```
|
193
|
+
|
194
|
+
Need a quick stack trace? Just use the `caller` option (you may surround with header and footer too via `wrapper`).
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
pd order_total, caller: true, wrapper: true
|
122
198
|
pd order_summary
|
123
199
|
pd order_details
|
124
200
|
```
|
125
201
|
|
202
|
+
Output:
|
203
|
+
|
204
|
+
```
|
205
|
+
(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)
|
206
|
+
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]]
|
207
|
+
********************************************************************************
|
208
|
+
[PD] /Users/User/ordering/order.rb:39
|
209
|
+
> pd order_total, caller: true, wrapper: true
|
210
|
+
=> 195.50
|
211
|
+
/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'
|
212
|
+
/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'
|
213
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
|
214
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
|
215
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
|
216
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in `block in require'
|
217
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:257:in `load_dependency'
|
218
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in `require'
|
219
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/railties-5.2.4.3/lib/rails/commands/server/server_command.rb:145:in `block in perform'
|
220
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/railties-5.2.4.3/lib/rails/commands/server/server_command.rb:142:in `tap'
|
221
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/railties-5.2.4.3/lib/rails/commands/server/server_command.rb:142:in `perform'
|
222
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
|
223
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
|
224
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
|
225
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/railties-5.2.4.3/lib/rails/command/base.rb:69:in `perform'
|
226
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/railties-5.2.4.3/lib/rails/command.rb:46:in `invoke'
|
227
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/railties-5.2.4.3/lib/rails/commands.rb:18:in `<main>'
|
228
|
+
/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'
|
229
|
+
/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'
|
230
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
|
231
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
|
232
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
|
233
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in `block in require'
|
234
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:257:in `load_dependency'
|
235
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/activesupport-5.2.4.3/lib/active_support/dependencies.rb:291:in `require'
|
236
|
+
/Users/User/code/sample-glimmer-dsl-opal-rails5-app/bin/rails:9:in `<top (required)>'
|
237
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/spring-2.1.0/lib/spring/client/rails.rb:28:in `load'
|
238
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/spring-2.1.0/lib/spring/client/rails.rb:28:in `call'
|
239
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/spring-2.1.0/lib/spring/client/command.rb:7:in `call'
|
240
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/spring-2.1.0/lib/spring/client.rb:30:in `run'
|
241
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/spring-2.1.0/bin/spring:49:in `<top (required)>'
|
242
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/spring-2.1.0/lib/spring/binstub.rb:11:in `load'
|
243
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/spring-2.1.0/lib/spring/binstub.rb:11:in `<top (required)>'
|
244
|
+
/Users/User/code/sample-glimmer-dsl-opal-rails5-app/bin/spring:15:in `require'
|
245
|
+
/Users/User/code/sample-glimmer-dsl-opal-rails5-app/bin/spring:15:in `<top (required)>'
|
246
|
+
bin/rails:3:in `load'
|
247
|
+
bin/rails:3:in `<main>'
|
248
|
+
********************************************************************************
|
249
|
+
(0.2ms) BEGIN
|
250
|
+
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
|
+
(0.3ms) COMMIT
|
252
|
+
[PD] /Users/User/ordering/order.rb:40
|
253
|
+
> pd order_summary
|
254
|
+
=> "Pragmatic Ruby Book"
|
255
|
+
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
|
+
(0.2ms) BEGIN
|
257
|
+
(0.2ms) COMMIT
|
258
|
+
[PD] /Users/User/ordering/order.rb:41
|
259
|
+
> pd order_details
|
260
|
+
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
261
|
+
```
|
262
|
+
|
263
|
+
Is the stack trace too long? Shorten it by passing number of lines to display to `caller` option.
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
pd order_total, caller: 3, wrapper: true
|
267
|
+
pd order_summary
|
268
|
+
pd order_details
|
269
|
+
```
|
270
|
+
|
271
|
+
```
|
272
|
+
(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)
|
273
|
+
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
|
+
********************************************************************************
|
275
|
+
[PD] /Users/User/ordering/order.rb:39
|
276
|
+
> pd order_total, caller: 3, wrapper: true
|
277
|
+
=> 195.50
|
278
|
+
/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
|
+
/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'
|
280
|
+
/Users/User/.rvm/gems/ruby-2.7.1/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
|
281
|
+
********************************************************************************
|
282
|
+
(0.2ms) BEGIN
|
283
|
+
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
|
+
(0.3ms) COMMIT
|
285
|
+
[PD] /Users/User/ordering/order.rb:40
|
286
|
+
> pd order_summary
|
287
|
+
=> "Pragmatic Ruby Book"
|
288
|
+
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
|
+
(0.2ms) BEGIN
|
290
|
+
(0.2ms) COMMIT
|
291
|
+
[PD] /Users/User/ordering/order.rb:41
|
292
|
+
> pd order_details
|
293
|
+
=> "[Hard Cover] Pragmatic Ruby Book - English Version"
|
294
|
+
```
|
295
|
+
|
296
|
+
There are many more options and powerful features in [puts_debuggerer](https://rubygems.org/gems/puts_debuggerer) as detailed below.
|
297
|
+
|
126
298
|
## Instructions
|
127
299
|
|
128
300
|
### Option 1: Bundler
|
@@ -130,7 +302,7 @@ pd order_details
|
|
130
302
|
Add the following to bundler's `Gemfile`.
|
131
303
|
|
132
304
|
```ruby
|
133
|
-
gem 'puts_debuggerer', '~> 0.
|
305
|
+
gem 'puts_debuggerer', '~> 0.10.0'
|
134
306
|
```
|
135
307
|
|
136
308
|
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.
|
@@ -140,7 +312,7 @@ This is the recommended way for [Rails](rubyonrails.org) apps. Optionally, you m
|
|
140
312
|
Or manually install and require library.
|
141
313
|
|
142
314
|
```bash
|
143
|
-
gem install puts_debuggerer -v0.
|
315
|
+
gem install puts_debuggerer -v0.10.0
|
144
316
|
```
|
145
317
|
|
146
318
|
```ruby
|
@@ -155,7 +327,7 @@ You may disable when needed by not requiring in Ruby or by adding an explicit re
|
|
155
327
|
|
156
328
|
```ruby
|
157
329
|
gem "awesome_print", require: false
|
158
|
-
gem "
|
330
|
+
gem "puts_debuggerer"
|
159
331
|
```
|
160
332
|
|
161
333
|
### Usage
|
@@ -209,8 +381,15 @@ Output:
|
|
209
381
|
=> "Hello Robert"
|
210
382
|
```
|
211
383
|
|
384
|
+
Alternatively, you may want to use `object.pd_inspect` (or alias `obj.pdi`) to
|
385
|
+
return formatted string without printing.
|
386
|
+
|
212
387
|
Happy puts_debuggerering!
|
213
388
|
|
389
|
+
#### Ruby Logger and Logging::Logger
|
390
|
+
|
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)).
|
392
|
+
|
214
393
|
### Options
|
215
394
|
|
216
395
|
Options enable more data to be displayed with puts_debuggerer, such as the caller
|
@@ -292,9 +471,25 @@ Header to include at the top of every print out.
|
|
292
471
|
|
293
472
|
Example:
|
294
473
|
|
474
|
+
```ruby
|
475
|
+
pd (x=1), header: true
|
476
|
+
```
|
477
|
+
|
478
|
+
Prints out:
|
479
|
+
|
480
|
+
```bash
|
481
|
+
********************************************************************************
|
482
|
+
[PD] /Users/User/example.rb:1
|
483
|
+
> pd (x=1), header: true
|
484
|
+
=> "1"
|
485
|
+
```
|
486
|
+
|
487
|
+
Global Option Example:
|
488
|
+
|
295
489
|
```ruby
|
296
490
|
PutsDebuggerer.header = true
|
297
491
|
pd (x=1)
|
492
|
+
pd (x=2)
|
298
493
|
```
|
299
494
|
|
300
495
|
Prints out:
|
@@ -302,8 +497,12 @@ Prints out:
|
|
302
497
|
```bash
|
303
498
|
********************************************************************************
|
304
499
|
[PD] /Users/User/example.rb:2
|
305
|
-
> pd x=1
|
500
|
+
> pd (x=1)
|
306
501
|
=> "1"
|
502
|
+
********************************************************************************
|
503
|
+
[PD] /Users/User/example.rb:3
|
504
|
+
> pd (x=2)
|
505
|
+
=> "2"
|
307
506
|
```
|
308
507
|
|
309
508
|
#### `PutsDebuggerer.footer`
|
@@ -317,18 +516,38 @@ Footer to include at the bottom of every print out.
|
|
317
516
|
|
318
517
|
Example:
|
319
518
|
|
519
|
+
```ruby
|
520
|
+
pd (x=1), footer: true
|
521
|
+
```
|
522
|
+
|
523
|
+
Prints out:
|
524
|
+
|
525
|
+
```bash
|
526
|
+
[PD] /Users/User/example.rb:1
|
527
|
+
> pd (x=1), footer: true
|
528
|
+
=> "1"
|
529
|
+
********************************************************************************
|
530
|
+
```
|
531
|
+
|
532
|
+
Global Option Example:
|
533
|
+
|
320
534
|
```ruby
|
321
535
|
PutsDebuggerer.footer = true
|
322
536
|
pd (x=1)
|
537
|
+
pd (x=2)
|
323
538
|
```
|
324
539
|
|
325
540
|
Prints out:
|
326
541
|
|
327
542
|
```bash
|
328
543
|
[PD] /Users/User/example.rb:2
|
329
|
-
> pd x=1
|
544
|
+
> pd (x=1)
|
330
545
|
=> "1"
|
331
546
|
********************************************************************************
|
547
|
+
[PD] /Users/User/example.rb:3
|
548
|
+
> pd (x=2)
|
549
|
+
=> "2"
|
550
|
+
********************************************************************************
|
332
551
|
```
|
333
552
|
|
334
553
|
#### `PutsDebuggerer.wrapper`
|
@@ -342,9 +561,26 @@ Wrapper to include at the top and bottom of every print out (both header and foo
|
|
342
561
|
|
343
562
|
Example:
|
344
563
|
|
564
|
+
```ruby
|
565
|
+
pd (x=1), wrapper: true
|
566
|
+
```
|
567
|
+
|
568
|
+
Prints out:
|
569
|
+
|
570
|
+
```bash
|
571
|
+
********************************************************************************
|
572
|
+
[PD] /Users/User/example.rb:1
|
573
|
+
> pd x=1, wrapper: true
|
574
|
+
=> "1"
|
575
|
+
********************************************************************************
|
576
|
+
```
|
577
|
+
|
578
|
+
Global Option Example:
|
579
|
+
|
345
580
|
```ruby
|
346
581
|
PutsDebuggerer.wrapper = true
|
347
582
|
pd (x=1)
|
583
|
+
pd (x=2)
|
348
584
|
```
|
349
585
|
|
350
586
|
Prints out:
|
@@ -352,14 +588,21 @@ Prints out:
|
|
352
588
|
```bash
|
353
589
|
********************************************************************************
|
354
590
|
[PD] /Users/User/example.rb:2
|
355
|
-
> pd x=1
|
591
|
+
> pd (x=1)
|
356
592
|
=> "1"
|
357
593
|
********************************************************************************
|
594
|
+
********************************************************************************
|
595
|
+
[PD] /Users/User/example.rb:3
|
596
|
+
> pd (x=2)
|
597
|
+
=> "2"
|
598
|
+
********************************************************************************
|
358
599
|
```
|
359
600
|
|
360
601
|
#### `PutsDebuggerer.source_line_count`
|
361
602
|
(default = `1`)
|
362
603
|
|
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.
|
605
|
+
|
363
606
|
Example:
|
364
607
|
|
365
608
|
```ruby
|
@@ -370,7 +613,7 @@ pd (true ||
|
|
370
613
|
Prints out:
|
371
614
|
|
372
615
|
```
|
373
|
-
[PD] /Users/User/example.rb:
|
616
|
+
[PD] /Users/User/example.rb:1
|
374
617
|
> pd (true ||
|
375
618
|
false), source_line_count: 2
|
376
619
|
=> "true"
|
@@ -396,9 +639,17 @@ Prints out:
|
|
396
639
|
#### `PutsDebuggerer.printer`
|
397
640
|
(default = `:puts`)
|
398
641
|
|
399
|
-
Printer is a global method symbol
|
400
|
-
|
642
|
+
Printer is a global method symbol, lambda expression, or logger to use in printing to the user.
|
643
|
+
|
644
|
+
Examples of a global method are `:puts` and `:print`.
|
401
645
|
An example of a lambda expression is `lambda {|output| Rails.logger.info(output)}`
|
646
|
+
Examples of a logger are a Ruby `Logger` instance or `Logging::Logger` instance
|
647
|
+
|
648
|
+
When a logger is supplied, it is automatically enhanced with a PutsDebuggerer formatter to use
|
649
|
+
when calling logger methods outside of PutsDebuggerer (e.g. `logger.error('msg')` will use `pd`)
|
650
|
+
|
651
|
+
Printer may be set to `false` to avoid printing and only return the formatted string.
|
652
|
+
It is equivalent of just calling `.pd_inspect` (or alias `.pdi`) on the object
|
402
653
|
|
403
654
|
Defaults to `:puts`
|
404
655
|
In Rails, it defaults to:
|
@@ -450,7 +701,7 @@ pd array
|
|
450
701
|
Prints out:
|
451
702
|
|
452
703
|
```bash
|
453
|
-
[PD] /Users/User/example.rb:
|
704
|
+
[PD] /Users/User/example.rb:4
|
454
705
|
> pd array
|
455
706
|
=> [1, [2, 3]]
|
456
707
|
```
|
@@ -555,6 +806,34 @@ Prints out:
|
|
555
806
|
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/context.rb:381:in \`evaluate\'
|
556
807
|
```
|
557
808
|
|
809
|
+
Global Option Example:
|
810
|
+
|
811
|
+
```ruby
|
812
|
+
# File Name: /Users/User/sample_app/lib/sample.rb
|
813
|
+
PutsDebuggerer.caller = 3 # always print 3 lines only of the stack trace
|
814
|
+
pd (x=1)
|
815
|
+
pd (x=2)
|
816
|
+
```
|
817
|
+
|
818
|
+
Prints out:
|
819
|
+
|
820
|
+
```bash
|
821
|
+
[PD] /Users/User/sample_app/lib/sample.rb:2
|
822
|
+
> pd (x=1)
|
823
|
+
=> "1"
|
824
|
+
/Users/User/sample_app/lib/master_samples.rb:368:in \`block (3 levels) in <top (required)>\'
|
825
|
+
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in \`eval\'
|
826
|
+
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in \`evaluate\'
|
827
|
+
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/context.rb:381:in \`evaluate\'
|
828
|
+
[PD] /Users/User/sample_app/lib/sample.rb:3
|
829
|
+
> pd (x=2)
|
830
|
+
=> "2"
|
831
|
+
/Users/User/sample_app/lib/master_samples.rb:368:in \`block (3 levels) in <top (required)>\'
|
832
|
+
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in \`eval\'
|
833
|
+
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in \`evaluate\'
|
834
|
+
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/context.rb:381:in \`evaluate\'
|
835
|
+
```
|
836
|
+
|
558
837
|
#### `PutsDebuggerer.run_at`
|
559
838
|
(default = nil)
|
560
839
|
|
@@ -678,7 +957,7 @@ Prints out `puts __caller_source_line__`
|
|
678
957
|
- IRB
|
679
958
|
- Rails Console.
|
680
959
|
|
681
|
-
It
|
960
|
+
It provides partial-compatibility for [Opal Ruby](https://opalrb.com/), with everything working except these features:
|
682
961
|
- File name display
|
683
962
|
- Line number display
|
684
963
|
- Source code call display
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.10.0
|
data/lib/pd.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'puts_debuggerer'
|
data/lib/puts_debuggerer.rb
CHANGED
@@ -1,18 +1,58 @@
|
|
1
|
-
require 'awesome_print' unless RUBY_PLATFORM == 'opal'
|
2
1
|
require 'stringio'
|
3
2
|
|
3
|
+
require 'puts_debuggerer/core_ext/kernel'
|
4
|
+
require 'puts_debuggerer/run_determiner'
|
5
|
+
require 'puts_debuggerer/source_file'
|
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
|
+
|
4
17
|
module PutsDebuggerer
|
5
18
|
SOURCE_LINE_COUNT_DEFAULT = 1
|
6
19
|
HEADER_DEFAULT = '*'*80
|
7
20
|
WRAPPER_DEFAULT = '*'*80
|
8
21
|
FOOTER_DEFAULT = '*'*80
|
22
|
+
LOGGER_FORMATTER_DECORATOR = proc { |original_formatter|
|
23
|
+
proc { |severity, datetime, progname, msg|
|
24
|
+
original_formatter.call(severity, datetime, progname, msg.pd_inspect)
|
25
|
+
}
|
26
|
+
}
|
27
|
+
LOGGING_LAYOUT_DECORATOR = proc {|original_layout|
|
28
|
+
original_layout.clone.tap do |layout|
|
29
|
+
layout.singleton_class.class_eval do
|
30
|
+
alias original_format_obj format_obj
|
31
|
+
def format_obj(obj)
|
32
|
+
obj.pdi # alias to pd_inspect
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
}
|
37
|
+
RETURN_DEFAULT = true
|
38
|
+
OBJECT_PRINTER_DEFAULT = lambda do |object, print_engine_options=nil, source_line_count=nil, run_number=nil|
|
39
|
+
lambda do
|
40
|
+
if object.is_a?(Exception) && object.respond_to?(:full_message)
|
41
|
+
puts object.full_message
|
42
|
+
elsif PutsDebuggerer.print_engine.is_a?(Proc)
|
43
|
+
PutsDebuggerer.print_engine.call(object)
|
44
|
+
else
|
45
|
+
send(PutsDebuggerer.print_engine, object)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
9
49
|
PRINTER_DEFAULT = :puts
|
10
50
|
PRINTER_RAILS = lambda do |output|
|
11
51
|
puts output if Rails.env.test?
|
12
52
|
Rails.logger.debug(output)
|
13
53
|
end
|
14
54
|
PRINT_ENGINE_DEFAULT = :ap
|
15
|
-
PRINTER_MESSAGE_INVALID = 'printer must be a valid global method symbol (e.g. :puts) or lambda/proc receiving a text arg'
|
55
|
+
PRINTER_MESSAGE_INVALID = 'printer must be a valid global method symbol (e.g. :puts), a logger, or a lambda/proc receiving a text arg'
|
16
56
|
PRINT_ENGINE_MESSAGE_INVALID = 'print_engine must be a valid global method symbol (e.g. :p, :ap or :pp) or lambda/proc receiving an object arg'
|
17
57
|
ANNOUNCER_DEFAULT = '[PD]'
|
18
58
|
FORMATTER_DEFAULT = -> (data) {
|
@@ -25,7 +65,6 @@ module PutsDebuggerer
|
|
25
65
|
puts data[:wrapper] if data[:wrapper]
|
26
66
|
}
|
27
67
|
CALLER_DEPTH_ZERO = 4 #depth includes pd + with_options method + nested block + build_pd_data method
|
28
|
-
OBJECT_RUN_AT = {}
|
29
68
|
STACK_TRACE_CALL_LINE_NUMBER_REGEX = /\:(\d+)\:in /
|
30
69
|
STACK_TRACE_CALL_SOURCE_FILE_REGEX = /[ ]*([^:]+)\:\d+\:in /
|
31
70
|
|
@@ -90,20 +129,6 @@ module PutsDebuggerer
|
|
90
129
|
# => "1"
|
91
130
|
attr_reader :header
|
92
131
|
|
93
|
-
def header=(value)
|
94
|
-
if value.equal?(true)
|
95
|
-
@header = HEADER_DEFAULT
|
96
|
-
elsif value == ''
|
97
|
-
@header = nil
|
98
|
-
else
|
99
|
-
@header = value
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def header?
|
104
|
-
!!@header
|
105
|
-
end
|
106
|
-
|
107
132
|
# Wrapper to include at the top and bottom of every print out (both header and footer).
|
108
133
|
# * Default value is `nil`
|
109
134
|
# * Value `true` enables wrapper as `'*'*80`
|
@@ -123,20 +148,6 @@ module PutsDebuggerer
|
|
123
148
|
# ********************************************************************************
|
124
149
|
attr_reader :wrapper
|
125
150
|
|
126
|
-
def wrapper=(value)
|
127
|
-
if value.equal?(true)
|
128
|
-
@wrapper = WRAPPER_DEFAULT
|
129
|
-
elsif value == ''
|
130
|
-
@wrapper = nil
|
131
|
-
else
|
132
|
-
@wrapper = value
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def wrapper?
|
137
|
-
!!@wrapper
|
138
|
-
end
|
139
|
-
|
140
151
|
# Footer to include at the bottom of every print out.
|
141
152
|
# * Default value is `nil`
|
142
153
|
# * Value `true` enables footer as `'*'*80`
|
@@ -155,24 +166,27 @@ module PutsDebuggerer
|
|
155
166
|
# => "1"
|
156
167
|
# ********************************************************************************
|
157
168
|
attr_reader :footer
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
169
|
+
|
170
|
+
['header', 'footer', 'wrapper'].each do |boundary_option|
|
171
|
+
define_method("#{boundary_option}=") do |value|
|
172
|
+
if value.equal?(true)
|
173
|
+
instance_variable_set(:"@#{boundary_option}", const_get(:"#{boundary_option.upcase}_DEFAULT"))
|
174
|
+
elsif value == ''
|
175
|
+
instance_variable_set(:"@#{boundary_option}", nil)
|
176
|
+
else
|
177
|
+
instance_variable_set(:"@#{boundary_option}", value)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
define_method("#{boundary_option}?") do
|
182
|
+
!!instance_variable_get(:"@#{boundary_option}")
|
166
183
|
end
|
167
184
|
end
|
168
185
|
|
169
|
-
|
170
|
-
|
171
|
-
end
|
172
|
-
|
173
|
-
# Printer is a global method symbol or lambda expression to use in printing to the user.
|
174
|
-
# Examples of global methods are `:puts` and `:print`.
|
186
|
+
# Printer is a global method symbol, lambda expression, or logger to use in printing to the user.
|
187
|
+
# Examples of a global method are `:puts` and `:print`.
|
175
188
|
# An example of a lambda expression is `lambda {|output| Rails.logger.ap(output)}`
|
189
|
+
# Examples of a logger are a Ruby `Logger` instance or `Logging::Logger` instance
|
176
190
|
#
|
177
191
|
# Defaults to `:puts`
|
178
192
|
# In Rails, it defaults to: `lambda {|output| Rails.logger.ap(output)}`
|
@@ -193,17 +207,37 @@ module PutsDebuggerer
|
|
193
207
|
|
194
208
|
def printer=(printer)
|
195
209
|
if printer.nil?
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
210
|
+
@printer = printer_default
|
211
|
+
elsif printer.is_a?(Logger)
|
212
|
+
@printer = printer
|
213
|
+
@logger_original_formatter = printer.formatter || Logger::Formatter.new
|
214
|
+
printer.formatter = LOGGER_FORMATTER_DECORATOR.call(@logger_original_formatter)
|
215
|
+
elsif printer.is_a?(Logging::Logger)
|
216
|
+
@printer = printer
|
217
|
+
@logging_original_layouts = printer.appenders.reduce({}) do |hash, appender|
|
218
|
+
hash.merge(appender => appender.layout)
|
219
|
+
end
|
220
|
+
printer.appenders.each do |appender|
|
221
|
+
appender.layout = LOGGING_LAYOUT_DECORATOR.call(appender.layout)
|
200
222
|
end
|
201
|
-
elsif printer.is_a?(Proc)
|
223
|
+
elsif printer == false || printer.is_a?(Proc) || printer.respond_to?(:log) # a logger
|
202
224
|
@printer = printer
|
203
225
|
else
|
204
226
|
@printer = method(printer).name rescue raise(PRINTER_MESSAGE_INVALID)
|
205
227
|
end
|
206
228
|
end
|
229
|
+
|
230
|
+
def printer_default
|
231
|
+
Object.const_defined?(:Rails) ? PRINTER_RAILS : PRINTER_DEFAULT
|
232
|
+
end
|
233
|
+
|
234
|
+
# Logger original formatter before it was decorated with PutsDebuggerer::LOGGER_FORMATTER_DECORATOR
|
235
|
+
# upon setting the logger as a printer.
|
236
|
+
attr_reader :logger_original_formatter
|
237
|
+
|
238
|
+
# Logging library original layouts before being decorated with PutsDebuggerer::LOGGING_LAYOUT_DECORATOR
|
239
|
+
# upon setting the Logging library logger as a printer.
|
240
|
+
attr_reader :logging_original_layouts
|
207
241
|
|
208
242
|
# Print engine is similar to `printer`, except it is focused on the scope of formatting
|
209
243
|
# the data object being printed (excluding metadata such as file name, line number,
|
@@ -232,13 +266,17 @@ module PutsDebuggerer
|
|
232
266
|
|
233
267
|
def print_engine=(engine)
|
234
268
|
if engine.nil?
|
235
|
-
@print_engine =
|
269
|
+
@print_engine = print_engine_default
|
236
270
|
elsif engine.is_a?(Proc)
|
237
271
|
@print_engine = engine
|
238
272
|
else
|
239
273
|
@print_engine = method(engine).name rescue raise(PRINT_ENGINE_MESSAGE_INVALID)
|
240
274
|
end
|
241
275
|
end
|
276
|
+
|
277
|
+
def print_engine_default
|
278
|
+
Object.const_defined?(:AwesomePrint) ? PRINT_ENGINE_DEFAULT : :p
|
279
|
+
end
|
242
280
|
|
243
281
|
# Announcer (e.g. [PD]) to announce every print out with (default: "[PD]")
|
244
282
|
#
|
@@ -430,44 +468,25 @@ module PutsDebuggerer
|
|
430
468
|
!!@run_at
|
431
469
|
end
|
432
470
|
|
433
|
-
|
434
|
-
|
435
|
-
def run_at_global_number=(value)
|
436
|
-
@run_at_global_number = value
|
437
|
-
end
|
438
|
-
|
439
|
-
def init_run_at_global_number
|
440
|
-
@run_at_global_number = 1
|
441
|
-
end
|
442
|
-
|
443
|
-
def increment_run_at_global_number
|
444
|
-
@run_at_global_number += 1
|
445
|
-
end
|
446
|
-
|
447
|
-
def reset_run_at_global_number
|
448
|
-
@run_at_global_number = nil
|
449
|
-
end
|
450
|
-
|
451
|
-
def run_at_number(object, run_at)
|
452
|
-
PutsDebuggerer::OBJECT_RUN_AT[[object,run_at]]
|
471
|
+
def determine_options(objects)
|
472
|
+
objects.delete_at(-1) if objects.size > 1 && objects.last.is_a?(Hash)
|
453
473
|
end
|
454
474
|
|
455
|
-
def
|
456
|
-
|
475
|
+
def determine_object(objects)
|
476
|
+
objects.compact.size > 1 ? objects : objects.first
|
457
477
|
end
|
458
478
|
|
459
|
-
def
|
460
|
-
|
479
|
+
def determine_run_at(options)
|
480
|
+
((options && options[:run_at]) || PutsDebuggerer.run_at)
|
461
481
|
end
|
462
482
|
|
463
|
-
def
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
483
|
+
def determine_printer(options)
|
484
|
+
if options && options.has_key?(:printer)
|
485
|
+
options[:printer]
|
486
|
+
else
|
487
|
+
PutsDebuggerer.printer
|
488
|
+
end
|
469
489
|
end
|
470
|
-
|
471
490
|
end
|
472
491
|
end
|
473
492
|
|
@@ -511,58 +530,56 @@ PutsDebuggerer.source_line_count = nil
|
|
511
530
|
# => "Show me the source of the bug: beattle"
|
512
531
|
# [PD] /Users/User/finance_calculator_app/pd_test.rb:4 "What line number am I?"
|
513
532
|
def pd(*objects)
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
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)
|
519
544
|
__with_pd_options__(options) do |print_engine_options|
|
520
|
-
run_number = PutsDebuggerer.
|
521
|
-
formatter_pd_data = __build_pd_data__(object, print_engine_options, PutsDebuggerer.source_line_count, run_number) #depth adds build method
|
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
|
522
547
|
stdout = $stdout
|
523
548
|
$stdout = sio = StringIO.new
|
524
549
|
PutsDebuggerer.formatter.call(formatter_pd_data)
|
525
550
|
$stdout = stdout
|
551
|
+
string = sio.string
|
526
552
|
if PutsDebuggerer.printer.is_a?(Proc)
|
527
|
-
PutsDebuggerer.printer.call(
|
528
|
-
|
529
|
-
|
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)
|
530
578
|
end
|
531
579
|
end
|
532
580
|
end
|
533
581
|
|
534
|
-
object
|
535
|
-
end
|
536
|
-
|
537
|
-
def __run_pd__(object, run_at)
|
538
|
-
run_pd = false
|
539
|
-
if run_at.nil?
|
540
|
-
run_pd = true
|
541
|
-
else
|
542
|
-
if PutsDebuggerer.run_at?
|
543
|
-
if PutsDebuggerer.run_at_global_number.nil?
|
544
|
-
PutsDebuggerer.init_run_at_global_number
|
545
|
-
else
|
546
|
-
PutsDebuggerer.increment_run_at_global_number
|
547
|
-
end
|
548
|
-
run_number = PutsDebuggerer.run_at_global_number
|
549
|
-
else
|
550
|
-
if PutsDebuggerer.run_at_number(object, run_at).nil?
|
551
|
-
PutsDebuggerer.init_run_at_number(object, run_at)
|
552
|
-
else
|
553
|
-
PutsDebuggerer.increment_run_at_number(object, run_at)
|
554
|
-
end
|
555
|
-
run_number = PutsDebuggerer.run_at_number(object, run_at)
|
556
|
-
end
|
557
|
-
if run_at.is_a?(Integer)
|
558
|
-
run_pd = true if run_at == run_number
|
559
|
-
elsif run_at.is_a?(Array)
|
560
|
-
run_pd = true if run_at.include?(run_number)
|
561
|
-
elsif run_at.is_a?(Range)
|
562
|
-
run_pd = true if run_at.cover?(run_number) || (run_at.end == -1 && run_number >= run_at.begin)
|
563
|
-
end
|
564
|
-
end
|
565
|
-
run_pd
|
582
|
+
printer ? object : string
|
566
583
|
end
|
567
584
|
|
568
585
|
# Provides caller line number starting 1 level above caller of
|
@@ -589,7 +606,7 @@ end
|
|
589
606
|
#
|
590
607
|
# prints out `lib/example.rb`
|
591
608
|
def __caller_file__(caller_depth=0)
|
592
|
-
caller[caller_depth] && caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_SOURCE_FILE_REGEX, 1]
|
609
|
+
result = caller[caller_depth] && caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_SOURCE_FILE_REGEX, 1]
|
593
610
|
end
|
594
611
|
|
595
612
|
|
@@ -606,24 +623,9 @@ def __caller_source_line__(caller_depth=0, source_line_count=nil, source_file=ni
|
|
606
623
|
source_file ||= __caller_file__(caller_depth+1)
|
607
624
|
source_line = ''
|
608
625
|
if source_file == '(irb)'
|
609
|
-
source_line = conf.io.line(source_line_number)
|
626
|
+
source_line = conf.io.line(source_line_number) # TODO handle multi-lines in source_line_count
|
610
627
|
else
|
611
|
-
|
612
|
-
if f.respond_to?(:readline) # Opal Ruby Compatibility
|
613
|
-
source_lines = []
|
614
|
-
begin
|
615
|
-
while f.lineno < source_line_number + source_line_count
|
616
|
-
file_line_number = f.lineno + 1
|
617
|
-
file_line = f.readline
|
618
|
-
if file_line_number >= source_line_number && file_line_number < source_line_number + source_line_count
|
619
|
-
source_lines << file_line
|
620
|
-
end
|
621
|
-
end
|
622
|
-
rescue EOFError
|
623
|
-
# Done
|
624
|
-
end
|
625
|
-
source_line = source_lines.join(' '*5)
|
626
|
-
end
|
628
|
+
source_line = PutsDebuggerer::SourceFile.new(source_file).source(source_line_count, source_line_number)
|
627
629
|
end
|
628
630
|
source_line
|
629
631
|
end
|
@@ -639,8 +641,11 @@ def __with_pd_options__(options=nil)
|
|
639
641
|
PutsDebuggerer.options = permanent_options
|
640
642
|
end
|
641
643
|
|
642
|
-
def __build_pd_data__(object, print_engine_options=nil, source_line_count=nil, run_number=nil)
|
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)
|
643
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
|
644
649
|
pd_data = {
|
645
650
|
announcer: PutsDebuggerer.announcer,
|
646
651
|
file: __caller_file__(depth)&.sub(PutsDebuggerer.app_path.to_s, ''),
|
@@ -648,31 +653,23 @@ def __build_pd_data__(object, print_engine_options=nil, source_line_count=nil, r
|
|
648
653
|
pd_expression: __caller_pd_expression__(depth, source_line_count),
|
649
654
|
run_number: run_number,
|
650
655
|
object: object,
|
651
|
-
object_printer:
|
652
|
-
if object.is_a?(Exception) && object.respond_to?(:full_message)
|
653
|
-
puts object.full_message
|
654
|
-
elsif PutsDebuggerer.print_engine.is_a?(Proc)
|
655
|
-
PutsDebuggerer.print_engine.call(object)
|
656
|
-
else
|
657
|
-
if print_engine_options.to_h.empty?
|
658
|
-
send(PutsDebuggerer.print_engine, object)
|
659
|
-
else
|
660
|
-
send(PutsDebuggerer.print_engine, object, print_engine_options) rescue send(PutsDebuggerer.print_engine, object)
|
661
|
-
end
|
662
|
-
end
|
663
|
-
end
|
656
|
+
object_printer: PutsDebuggerer::OBJECT_PRINTER_DEFAULT.call(object, print_engine_options, source_line_count, run_number)
|
664
657
|
}
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
pd_data[:caller] = caller[start_depth..caller_depth].to_a
|
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}?")
|
669
661
|
end
|
670
|
-
pd_data[:header] = PutsDebuggerer.header if PutsDebuggerer.header?
|
671
|
-
pd_data[:wrapper] = PutsDebuggerer.wrapper if PutsDebuggerer.wrapper?
|
672
|
-
pd_data[:footer] = PutsDebuggerer.footer if PutsDebuggerer.footer?
|
673
662
|
pd_data
|
674
663
|
end
|
675
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
|
+
|
676
673
|
def __format_pd_expression__(expression, object)
|
677
674
|
"\n > #{expression}\n =>"
|
678
675
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module PutsDebuggerer
|
2
|
+
module RunDeterminer
|
3
|
+
OBJECT_RUN_AT = {}
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_reader :run_at_global_number
|
7
|
+
|
8
|
+
def run_at_global_number=(value)
|
9
|
+
@run_at_global_number = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def init_run_at_global_number
|
13
|
+
@run_at_global_number = 1
|
14
|
+
end
|
15
|
+
|
16
|
+
def increment_run_at_global_number
|
17
|
+
@run_at_global_number += 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset_run_at_global_number
|
21
|
+
@run_at_global_number = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_at_number(object, run_at)
|
25
|
+
OBJECT_RUN_AT[[object,run_at]]
|
26
|
+
end
|
27
|
+
|
28
|
+
def init_run_at_number(object, run_at)
|
29
|
+
OBJECT_RUN_AT[[object,run_at]] = 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def increment_run_at_number(object, run_at)
|
33
|
+
OBJECT_RUN_AT[[object,run_at]] += 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def reset_run_at_number(object, run_at)
|
37
|
+
OBJECT_RUN_AT.delete([object, run_at])
|
38
|
+
end
|
39
|
+
|
40
|
+
def reset_run_at_numbers
|
41
|
+
OBJECT_RUN_AT.clear
|
42
|
+
end
|
43
|
+
|
44
|
+
def run_number(object, run_at)
|
45
|
+
run_at_global_number || run_at_number(object, run_at)
|
46
|
+
end
|
47
|
+
|
48
|
+
def run_pd?(object, run_at)
|
49
|
+
run_pd = false
|
50
|
+
if run_at.nil?
|
51
|
+
run_pd = true
|
52
|
+
else
|
53
|
+
run_number = determine_run_number(object, run_at)
|
54
|
+
run_pd = determine_run_pd(run_at, run_number)
|
55
|
+
end
|
56
|
+
run_pd
|
57
|
+
end
|
58
|
+
|
59
|
+
def determine_run_number(object, run_at)
|
60
|
+
if PutsDebuggerer.run_at? # check if global option is set
|
61
|
+
determine_global_run_number
|
62
|
+
else
|
63
|
+
determine_local_run_number(object, run_at)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def determine_global_run_number
|
68
|
+
if PutsDebuggerer::RunDeterminer.run_at_global_number.nil?
|
69
|
+
PutsDebuggerer::RunDeterminer.init_run_at_global_number
|
70
|
+
else
|
71
|
+
PutsDebuggerer::RunDeterminer.increment_run_at_global_number
|
72
|
+
end
|
73
|
+
PutsDebuggerer::RunDeterminer.run_at_global_number
|
74
|
+
end
|
75
|
+
|
76
|
+
def determine_local_run_number(object, run_at)
|
77
|
+
if PutsDebuggerer::RunDeterminer.run_at_number(object, run_at).nil?
|
78
|
+
PutsDebuggerer::RunDeterminer.init_run_at_number(object, run_at)
|
79
|
+
else
|
80
|
+
PutsDebuggerer::RunDeterminer.increment_run_at_number(object, run_at)
|
81
|
+
end
|
82
|
+
PutsDebuggerer::RunDeterminer.run_at_number(object, run_at)
|
83
|
+
end
|
84
|
+
|
85
|
+
def determine_run_pd(run_at, run_number)
|
86
|
+
if run_at.is_a?(Integer)
|
87
|
+
determine_run_pd_integer(run_at, run_number)
|
88
|
+
elsif run_at.is_a?(Array)
|
89
|
+
determine_run_pd_array(run_at, run_number)
|
90
|
+
elsif run_at.is_a?(Range)
|
91
|
+
determine_run_pd_range(run_at, run_number)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def determine_run_pd_integer(run_at, run_number)
|
96
|
+
run_pd = true if run_at == run_number
|
97
|
+
end
|
98
|
+
|
99
|
+
def determine_run_pd_array(run_at, run_number)
|
100
|
+
run_pd = true if run_at.include?(run_number)
|
101
|
+
end
|
102
|
+
|
103
|
+
def determine_run_pd_range(run_at, run_number)
|
104
|
+
run_pd = true if run_at.cover?(run_number) || (run_at.end == -1 && run_number >= run_at.begin)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module PutsDebuggerer
|
2
|
+
class SourceFile
|
3
|
+
def initialize(file_path)
|
4
|
+
@file = File.new(file_path)
|
5
|
+
end
|
6
|
+
|
7
|
+
def source(source_line_count, source_line_number)
|
8
|
+
@source = ''
|
9
|
+
# For Opal Ruby compatibility, skip source lines if file does not respond to readline (as in Opal)
|
10
|
+
lines = source_lines(source_line_count, source_line_number)
|
11
|
+
@source = lines.join(' '*5) if @file.respond_to?(:readline)
|
12
|
+
@source
|
13
|
+
end
|
14
|
+
|
15
|
+
def source_lines(source_line_count, source_line_number)
|
16
|
+
lines = []
|
17
|
+
begin
|
18
|
+
while @file.lineno < source_line_number + source_line_count
|
19
|
+
file_line_number = @file.lineno + 1
|
20
|
+
file_line = @file.readline
|
21
|
+
if file_line_number >= source_line_number && file_line_number < source_line_number + source_line_count
|
22
|
+
lines << file_line
|
23
|
+
end
|
24
|
+
end
|
25
|
+
rescue EOFError
|
26
|
+
# Done
|
27
|
+
end
|
28
|
+
lines
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
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.10.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-
|
11
|
+
date: 2020-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_print
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: 0.3.4
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: logging
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 2.3.0
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 2.3.0
|
153
167
|
description: |
|
154
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.
|
155
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.
|
@@ -166,7 +180,11 @@ files:
|
|
166
180
|
- LICENSE.txt
|
167
181
|
- README.md
|
168
182
|
- VERSION
|
183
|
+
- lib/pd.rb
|
169
184
|
- lib/puts_debuggerer.rb
|
185
|
+
- lib/puts_debuggerer/core_ext/kernel.rb
|
186
|
+
- lib/puts_debuggerer/run_determiner.rb
|
187
|
+
- lib/puts_debuggerer/source_file.rb
|
170
188
|
homepage: http://github.com/AndyObtiva/puts_debuggerer
|
171
189
|
licenses:
|
172
190
|
- MIT
|
@@ -186,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
204
|
- !ruby/object:Gem::Version
|
187
205
|
version: '0'
|
188
206
|
requirements: []
|
189
|
-
rubygems_version: 3.1.
|
207
|
+
rubygems_version: 3.1.4
|
190
208
|
signing_key:
|
191
209
|
specification_version: 4
|
192
210
|
summary: Ruby library for improved puts debugging, automatically displaying bonus
|