puts_debuggerer 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +144 -21
  3. data/lib/puts_debuggerer.rb +191 -36
  4. metadata +14 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 74eb84d4e3c40ce1f68dd0142da2e4579a7cf2a7
4
- data.tar.gz: 658504f16ce3f3522a4dba972701fb05907a5088
3
+ metadata.gz: a76ad1423ec2f3a99ddc81f5180ff557bbef1a8b
4
+ data.tar.gz: 86c7f3bec6285fa098500f7135da7b3cefd3df0f
5
5
  SHA512:
6
- metadata.gz: 25fc5da47a71afcae5d14ce8270761ddc7a637147722c778f0a18598f5b9c8a215b595c85415516e3877c6a51ba16468727d45138c024a508023a08111282a12
7
- data.tar.gz: 9617fe34c02aee117c6a3741fab8edfc6700549da37d7e582d73c02be1b769072c4c36b57c761f06c097f7ea5033d4aca108a3d0d173f8f97c8ce77ab7a2748f
6
+ metadata.gz: c9e6a0d82247b43c84370708b98629ba19da1eaef472ae0980940e04ac4b6e4a1785fbe010aa14026ce35a63de95cb14160c62d9c9b89782eb0b1276519592f7
7
+ data.tar.gz: 236fd33a65d78794613d5a0de3e26afcf784cf88c9592773eba76e9ee4ceb17020a6eb2176c6a8e793d71b05e75933a596447f00ce3d86bb468514d330e9af01
data/README.md CHANGED
@@ -1,11 +1,18 @@
1
- # puts_debuggerer v0.4.0
1
+ # puts_debuggerer v0.5.0
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
5
 
6
- Ruby tools for improved puts debugging, automatically displaying bonus useful information such as file, line number and source code.
6
+ Yes, many of us avoid debuggers like the plague and clamp on to our puts
7
+ statements like an umbrella in a stormy day.
8
+ Why not make it official and have puts debugging become its own perfectly
9
+ legitimate thing?!!
7
10
 
8
- Partially inspired by this blog post:
11
+ And thus, puts_debuggerer was born. A guilt-free puts debugger Ruby gem FTW!
12
+
13
+ In other words, puts_debuggerer is a Ruby library for improved puts debugging, automatically displaying bonus useful information such as source line number and source code.
14
+
15
+ Partially inspired (only partially ;) by this blog post:
9
16
  https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html
10
17
  (Credit to Tenderlove.)
11
18
 
@@ -16,7 +23,7 @@ https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html
16
23
  Add the following to bundler's `Gemfile`.
17
24
 
18
25
  ```ruby
19
- gem 'puts_debuggerer', '~> 0.4.0'
26
+ gem 'puts_debuggerer', '~> 0.5.0'
20
27
  ```
21
28
 
22
29
  ### Manual
@@ -24,7 +31,7 @@ gem 'puts_debuggerer', '~> 0.4.0'
24
31
  Or manually install and require library.
25
32
 
26
33
  ```bash
27
- gem install puts_debuggerer -v0.4.0
34
+ gem install puts_debuggerer -v0.5.0
28
35
  ```
29
36
 
30
37
  ```ruby
@@ -33,8 +40,8 @@ require 'puts_debuggerer'
33
40
 
34
41
  ### Usage
35
42
 
36
- Simply invoke global `pd` method anywhere and it prints file, line number,
37
- source code in addition to output (works even in IRB).
43
+ Simply invoke global `pd` method anywhere and it prints source file, line
44
+ number, and source code in addition to output (works even in IRB).
38
45
  If the argument is a literal value with no interpolation, the print out is
39
46
  simplified by not showing source code matching output.
40
47
 
@@ -46,7 +53,7 @@ Quickly locate printed lines using Find feature (e.g. CTRL+F) by looking for:
46
53
  This gives you the added benefit of easily removing your `pd` statements later
47
54
  on.
48
55
 
49
- This can easily be augmented with a print engine like `awesome_print` and
56
+ This can easily be augmented with a print engine like [awesome_print](https://github.com/awesome-print/awesome_print) and
50
57
  customized to format output differently as per options below.
51
58
 
52
59
  Happy puts_debuggerering!
@@ -64,14 +71,45 @@ Example Printout:
64
71
 
65
72
  ```bash
66
73
  [PD] /Users/User/finance_calculator_app/pd_test.rb:3
67
- > ("Show me the source of the bug: #{bug}").inspect
74
+ > pd "Show me the source of the bug: #{bug}"
68
75
  => "Show me the source of the bug: beattle"
69
76
  [PD] /Users/User/finance_calculator_app/pd_test.rb:4 "What line number am I?"
70
77
  ```
71
78
 
72
79
  ### Options
73
80
 
74
- #### `PutsDebuggerer.app_path` (default = `nil`)
81
+ Options enable more data to be displayed with puts_debuggerer, such as the caller
82
+ backtrace, header, and footer. They also allow customization of output format.
83
+
84
+ Options can be set as a global configuration or piecemeal per puts statement.
85
+
86
+ Global configuration is done via `PutsDebuggerer` module attribute writers.
87
+ On the other hand, piecemeal options can be passed to the `pd` global method as
88
+ the second argument.
89
+
90
+ Example:
91
+
92
+ ```ruby
93
+ # File Name: /Users/User/project/piecemeal.rb
94
+ data = [1, [2, 3]]
95
+ pd data, header: '>'*80, footer: '<'*80, announcer: " -<[PD]>-\n "
96
+ ```
97
+
98
+ Prints out:
99
+
100
+ ```bash
101
+ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
102
+ -<[PD]>-
103
+ /Users/User/project/piecemeal.rb:3
104
+ > pd data
105
+ => [1, [2, 3]]
106
+ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
107
+ ```
108
+
109
+ Details about all the available options are included below.
110
+
111
+ #### `PutsDebuggerer.app_path`
112
+ (default = `nil`)
75
113
 
76
114
  Sets absolute application path. Makes `pd` file output relative to it.
77
115
  If [Rails](rubyonrails.org) was detected, it is automatically defaulted to `Rails.root.to_s`
@@ -88,12 +126,13 @@ Example Printout:
88
126
 
89
127
  ```bash
90
128
  [PD] pd_test.rb:4
91
- > ("Show me the source of the bug: #{bug}").inspect
129
+ > pd "Show me the source of the bug: #{bug}"
92
130
  => "Show me the source of the bug: beattle"
93
131
  [PD] pd_test.rb:5 "What line number am I?"
94
132
  ```
95
133
 
96
- #### `PutsDebuggerer.header` (default = `nil`)
134
+ #### `PutsDebuggerer.header`
135
+ (default = `'*'*80`)
97
136
 
98
137
  Header to include at the top of every print out.
99
138
  * Default value is `nil`
@@ -113,11 +152,12 @@ Prints out:
113
152
  ```bash
114
153
  ********************************************************************************
115
154
  [PD] /Users/User/example.rb:2
116
- > (x=1).inspect
155
+ > pd x=1
117
156
  => "1"
118
157
  ```
119
158
 
120
- #### `PutsDebuggerer.footer` (default = `nil`)
159
+ #### `PutsDebuggerer.footer`
160
+ (default = `'*'*80`)
121
161
 
122
162
  Footer to include at the bottom of every print out.
123
163
  * Default value is `nil`
@@ -136,17 +176,19 @@ Prints out:
136
176
 
137
177
  ```bash
138
178
  [PD] /Users/User/example.rb:2
139
- > (x=1).inspect
179
+ > pd x=1
140
180
  => "1"
141
181
  ********************************************************************************
142
182
  ```
143
183
 
144
- #### `PutsDebuggerer.print_engine` (default = `:p`)
184
+ #### `PutsDebuggerer.print_engine`
185
+ (default = `:p`)
145
186
 
146
187
  Print engine to use in object printout (e.g. `p`, `ap`, `pp`).
147
188
  It is represented by the print engine's global method name as a symbol
148
- (e.g. `:ap` for awesome_print).
189
+ (e.g. `:ap` for [awesome_print](https://github.com/awesome-print/awesome_print)).
149
190
  Defaults to Ruby's built-in `p` method identified by the symbol `:p`.
191
+ If it finds [awesome_print](https://github.com/awesome-print/awesome_print) loaded, it defaults to `ap` as `:ap` instead.
150
192
 
151
193
  Example:
152
194
 
@@ -162,7 +204,7 @@ Prints out:
162
204
 
163
205
  ```bash
164
206
  [PD] /Users/User/example.rb:5
165
- > (array).inspect
207
+ > pd array
166
208
  => [
167
209
  [0] 1,
168
210
  [1] [
@@ -172,7 +214,8 @@ Prints out:
172
214
  ]
173
215
  ```
174
216
 
175
- #### `PutsDebuggerer.announcer` (default = `"[PD]"`)
217
+ #### `PutsDebuggerer.announcer`
218
+ (default = `"[PD]"`)
176
219
 
177
220
  Announcer (e.g. `[PD]`) to announce every print out with (default: `"[PD]"`)
178
221
 
@@ -188,10 +231,89 @@ Prints out:
188
231
  ```bash
189
232
  *** PD ***
190
233
  /Users/User/example.rb:2
191
- > (x=1).inspect
234
+ > pd x=1
192
235
  => "1"
193
236
  ```
194
237
 
238
+ #### `PutsDebuggerer.formatter`
239
+ (default = `PutsDebuggerer::FORMATTER_DEFAULT`)
240
+
241
+ Formatter used in every print out
242
+ Passed a data argument with the following keys:
243
+ * :announcer (string)
244
+ * :caller (array)
245
+ * :file (string)
246
+ * :footer (string)
247
+ * :header (string)
248
+ * :line_number (string)
249
+ * :pd_expression (string)
250
+ * :object (object)
251
+ * :object_printer (proc)
252
+
253
+ NOTE: data for :object_printer is not a string, yet a proc that must
254
+ be called to output value. It is a proc as it automatically handles usage
255
+ of print_engine and encapsulates its details. In any case, data for :object
256
+ is available should one want to avoid altogether.
257
+
258
+ Example:
259
+
260
+ ```ruby
261
+ PutsDebuggerer.formatter = -> (data) {
262
+ puts "-<#{data[:announcer]}>-"
263
+ puts "HEADER: #{data[:header]}"
264
+ puts "FILE: #{data[:file]}"
265
+ puts "LINE: #{data[:line_number]}"
266
+ puts "EXPRESSION: #{data[:pd_expression]}"
267
+ print "PRINT OUT: "
268
+ data[:object_printer].call
269
+ puts "CALLER: #{data[:caller].to_a.first}"
270
+ puts "FOOTER: #{data[:footer]}"
271
+ }
272
+ pd (x=1)
273
+ ```
274
+
275
+ Prints out:
276
+
277
+ ```bash
278
+ -<[PD]>-
279
+ FILE: /Users/User/example.rb
280
+ HEADER: ********************************************************************************
281
+ LINE: 9
282
+ EXPRESSION: x=1
283
+ PRINT OUT: 1
284
+ CALLER: #/Users/User/master_examples.rb:83:in `block (3 levels) in <top (required)>'
285
+ FOOTER: ********************************************************************************
286
+ ```
287
+
288
+ #### `PutsDebuggerer.caller`
289
+ (default = nil)
290
+
291
+ Caller backtrace included at the end of every print out
292
+ Passed an argument of true/false, nil, or depth as an integer.
293
+ * true and -1 means include full caller backtrace
294
+ * false and nil means do not include caller backtrace
295
+ * depth (0-based) means include limited caller backtrace depth
296
+
297
+ Example:
298
+
299
+ ```ruby
300
+ # File Name: /Users/User/sample_app/lib/sample.rb
301
+ PutsDebuggerer.caller = 3
302
+ pd (x=1)
303
+ ```
304
+
305
+ Prints out:
306
+
307
+ ```bash
308
+ [PD] /Users/User/sample_app/lib/sample.rb:3
309
+ > pd x=1
310
+ => "1"
311
+ /Users/User/sample_app/lib/master_samples.rb:368:in \`block (3 levels) in <top (required)>\'
312
+ /Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in \`eval\'
313
+ /Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in \`evaluate\'
314
+ /Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/context.rb:381:in \`evaluate\'
315
+ ```
316
+
195
317
  ### Bonus
196
318
 
197
319
  puts_debuggerer comes with the following bonus utility methods:
@@ -238,7 +360,8 @@ Prints out `puts __caller_source_line__`
238
360
 
239
361
  ## Release Notes
240
362
 
241
- * v0.4.0: custom print engine (e.g. ap), custom announcer, IRB support
363
+ * v0.5.0: custom formatter, caller backtrace, per-puts piecemeal options, and multi-line support
364
+ * v0.4.0: custom print engine (e.g. ap), custom announcer, and IRB support
242
365
  * v0.3.0: header/footer support, multi-line printout, improved format
243
366
  * v0.2.0: App path exclusion support, Rails root support, improved format
244
367
  * v0.1.0: File/line/expression print out
@@ -1,9 +1,20 @@
1
+ require 'ripper'
2
+
1
3
  module PutsDebuggerer
2
4
  HEADER_DEFAULT = '*'*80
3
5
  FOOTER_DEFAULT = '*'*80
4
6
  PRINT_ENGINE_DEFAULT = :p
5
7
  PRINT_ENGINE_MESSAGE_INVALID = 'print_engine must be a valid global method symbol (e.g. :p or :puts)'
6
8
  ANNOUNCER_DEFAULT = '[PD]'
9
+ FORMATTER_DEFAULT = -> (data) {
10
+ puts data[:header] if data[:header]
11
+ print "#{data[:announcer]} #{data[:file]}:#{data[:line_number]}#{__format_pd_expression__(data[:pd_expression], data[:object])} "
12
+ data[:object_printer].call
13
+ puts data[:caller].map {|l| ' ' + l} unless data[:caller].to_a.empty?
14
+ puts data[:footer] if data[:footer]
15
+ }
16
+ CALLER_DEPTH_ZERO = 4 #depth includes pd + with_options method + nested block + build_pd_data method
17
+
7
18
  class << self
8
19
  # Application root path to exclude when printing out file path
9
20
  #
@@ -16,13 +27,13 @@ module PutsDebuggerer
16
27
  # Prints out:
17
28
  #
18
29
  # [PD] lib/sample.rb:3
19
- # > (x=1).inspect
30
+ # > pd x=1
20
31
  # => "1"
21
- def app_path
22
- (@app_path || Rails.root.to_s) rescue nil
23
- end
32
+ attr_reader :app_path
24
33
 
25
- attr_writer :app_path
34
+ def app_path=(path)
35
+ @app_path = (path || Rails.root.to_s) rescue nil
36
+ end
26
37
 
27
38
  # Header to include at the top of every print out.
28
39
  # * Default value is `nil`
@@ -39,7 +50,7 @@ module PutsDebuggerer
39
50
  #
40
51
  # ********************************************************************************
41
52
  # [PD] /Users/User/example.rb:2
42
- # > (x=1).inspect
53
+ # > pd x=1
43
54
  # => "1"
44
55
  attr_reader :header
45
56
 
@@ -68,10 +79,10 @@ module PutsDebuggerer
68
79
  # PutsDebuggerer.footer = true
69
80
  # pd (x=1)
70
81
  #
71
- # Prints out
82
+ # Prints out:
72
83
  #
73
84
  # [PD] /Users/User/example.rb:2
74
- # > (x=1).inspect
85
+ # > pd x=1
75
86
  # => "1"
76
87
  # ********************************************************************************
77
88
  attr_reader :footer
@@ -94,6 +105,7 @@ module PutsDebuggerer
94
105
  # It is represented by the print engine's global method name as a symbol
95
106
  # (e.g. `:ap` for awesome_print).
96
107
  # Defaults to Ruby's built-in `p` method identified by the symbol `:p`.
108
+ # If it finds awesome_print loaded, it defaults to `ap` as `:ap` instead.
97
109
  #
98
110
  # Example:
99
111
  #
@@ -103,10 +115,10 @@ module PutsDebuggerer
103
115
  # array = [1, [2, 3]]
104
116
  # pd array
105
117
  #
106
- # Prints out
118
+ # Prints out:
107
119
  #
108
120
  # [PD] /Users/User/example.rb:5
109
- # > (array).inspect
121
+ # > pd array
110
122
  # => [
111
123
  # [0] 1,
112
124
  # [1] [
@@ -118,7 +130,7 @@ module PutsDebuggerer
118
130
 
119
131
  def print_engine=(engine)
120
132
  if engine.nil?
121
- @print_engine = PRINT_ENGINE_DEFAULT
133
+ @print_engine = method(:ap).name rescue PRINT_ENGINE_DEFAULT
122
134
  else
123
135
  @print_engine = method(engine).name rescue raise(PRINT_ENGINE_MESSAGE_INVALID)
124
136
  end
@@ -131,22 +143,130 @@ module PutsDebuggerer
131
143
  # PutsDebuggerer.announcer = "*** PD ***\n "
132
144
  # pd (x=1)
133
145
  #
134
- # Prints out
146
+ # Prints out:
135
147
  #
136
148
  # *** PD ***
137
149
  # /Users/User/example.rb:2
138
- # > (x=1).inspect
139
- # => "1"
150
+ # > pd x=1
151
+ # => 1
140
152
  attr_reader :announcer
141
153
 
142
154
  def announcer=(text)
143
155
  @announcer = text.nil? ? ANNOUNCER_DEFAULT : text
144
156
  end
157
+
158
+ # Formatter used in every print out
159
+ # Passed a data argument with the following keys:
160
+ # * :announcer (string)
161
+ # * :caller (array)
162
+ # * :file (string)
163
+ # * :footer (string)
164
+ # * :header (string)
165
+ # * :line_number (string)
166
+ # * :pd_expression (string)
167
+ # * :object (object)
168
+ # * :object_printer (proc)
169
+ #
170
+ # NOTE: data for :object_printer is not a string, yet a proc that must
171
+ # be called to output value. It is a proc as it automatically handles usage
172
+ # of print_engine and encapsulates its details. In any case, data for :object
173
+ # is available should one want to avoid altogether.
174
+ #
175
+ # Example:
176
+ #
177
+ # PutsDebuggerer.formatter = -> (data) {
178
+ # puts "-<#{data[:announcer]}>-"
179
+ # puts "HEADER: #{data[:header]}"
180
+ # puts "FILE: #{data[:file]}"
181
+ # puts "LINE: #{data[:line_number]}"
182
+ # puts "EXPRESSION: #{data[:pd_expression]}"
183
+ # print "PRINT OUT: "
184
+ # data[:object_printer].call
185
+ # puts "CALLER: #{data[:caller].to_a.first}"
186
+ # puts "FOOTER: #{data[:footer]}"
187
+ # }
188
+ # pd (x=1)
189
+ #
190
+ # Prints out:
191
+ #
192
+ # -<[PD]>-
193
+ # FILE: /Users/User/example.rb
194
+ # HEADER: ********************************************************************************
195
+ # LINE: 9
196
+ # EXPRESSION: x=1
197
+ # PRINT OUT: 1
198
+ # CALLER: #/Users/User/master_examples.rb:83:in `block (3 levels) in <top (required)>'
199
+ # FOOTER: ********************************************************************************
200
+ attr_reader :formatter
201
+
202
+ def formatter=(formatter_proc)
203
+ @formatter = formatter_proc.nil? ? FORMATTER_DEFAULT : formatter_proc
204
+ end
205
+
206
+ # Caller backtrace included at the end of every print out
207
+ # Passed an argument of true/false, nil, or depth as an integer.
208
+ # * true and -1 means include full caller backtrace
209
+ # * false and nil means do not include caller backtrace
210
+ # * depth (0-based) means include limited caller backtrace depth
211
+ #
212
+ # Example:
213
+ #
214
+ # # File Name: /Users/User/sample_app/lib/sample.rb
215
+ # PutsDebuggerer.caller = 3
216
+ # pd (x=1)
217
+ #
218
+ # Prints out:
219
+ #
220
+ # [PD] /Users/User/sample_app/lib/sample.rb:3
221
+ # > pd x=1
222
+ # => "1"
223
+ # /Users/User/sample_app/lib/master_samples.rb:368:in `block (3 levels) in <top (required)>'
224
+ # /Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in `eval'
225
+ # /Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in `evaluate'
226
+ # /Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/context.rb:381:in `evaluate'
227
+ attr_reader :caller
228
+
229
+ def caller=(value)
230
+ if value.equal?(true)
231
+ @caller = -1 #needed for upper bound in pd method
232
+ else
233
+ @caller = value
234
+ end
235
+ end
236
+
237
+ def caller?
238
+ !!caller
239
+ end
240
+
241
+
242
+ # Options as a hash. Useful for reading and backing up options
243
+ def options
244
+ {
245
+ header: header,
246
+ footer: footer,
247
+ print_engine: print_engine,
248
+ app_path: app_path,
249
+ announcer: announcer,
250
+ formatter: formatter,
251
+ caller: caller
252
+ }
253
+ end
254
+
255
+ # Sets options included in hash
256
+ def options=(hash)
257
+ hash.each do |option, value|
258
+ send("#{option}=", value)
259
+ end
260
+ end
261
+
145
262
  end
146
263
  end
147
264
 
148
265
  PutsDebuggerer.print_engine = PutsDebuggerer::PRINT_ENGINE_DEFAULT
149
266
  PutsDebuggerer.announcer = PutsDebuggerer::ANNOUNCER_DEFAULT
267
+ PutsDebuggerer.formatter = PutsDebuggerer::FORMATTER_DEFAULT
268
+ PutsDebuggerer.app_path = nil
269
+ PutsDebuggerer.caller = nil
150
270
 
151
271
  # Prints object with bonus info such as file name, line number and source
152
272
  # expression. Optionally prints out header and footer.
@@ -174,22 +294,15 @@ PutsDebuggerer.announcer = PutsDebuggerer::ANNOUNCER_DEFAULT
174
294
  # Example Printout:
175
295
  #
176
296
  # [PD] /Users/User/finance_calculator_app/pd_test.rb:3
177
- # > ("Show me the source of the bug: #{bug}").inspect
297
+ # > pd "Show me the source of the bug: #{bug}"
178
298
  # => "Show me the source of the bug: beattle"
179
299
  # [PD] /Users/User/finance_calculator_app/pd_test.rb:4 "What line number am I?"
180
300
  def pd(object, options=nil)
181
- header = PutsDebuggerer.header? ? "#{PutsDebuggerer.header}\n" : ''
182
- announcer = PutsDebuggerer.announcer
183
- file = __caller_file__(1).sub(PutsDebuggerer.app_path.to_s, '')
184
- line_number = __caller_line_number__(1)
185
- pd_expression = __caller_pd_expression__(object)
186
- print "#{header}#{announcer} #{file}:#{line_number}#{pd_expression} "
187
- if options.nil? || options == {}
188
- send(PutsDebuggerer.print_engine, object)
189
- else
190
- send(PutsDebuggerer.print_engine, object, options) rescue send(PutsDebuggerer.print_engine, object)
301
+ __with_pd_options__(options) do |print_engine_options|
302
+ formatter_pd_data = __build_pd_data__(object, print_engine_options) #depth adds build method
303
+ PutsDebuggerer.formatter.call(formatter_pd_data)
191
304
  end
192
- puts PutsDebuggerer.footer if PutsDebuggerer.footer?
305
+ nil
193
306
  end
194
307
 
195
308
 
@@ -239,9 +352,15 @@ def __caller_source_line__(caller_depth=0)
239
352
  if source_file == '(irb)'
240
353
  source_line = conf.io.line(source_line_number)
241
354
  else
242
- File.open(source_file, 'r') do |f|
243
- lines = f.readlines
244
- source_line = lines[source_line_number-1]
355
+ f = File.new(source_file)
356
+ source_line = ''
357
+ done = false
358
+ f.each_line do |line|
359
+ if !done && f.lineno == source_line_number
360
+ source_line << line
361
+ done = true if Ripper.sexp_raw(source_line)
362
+ source_line_number+=1
363
+ end
245
364
  end
246
365
  end
247
366
  source_line
@@ -249,17 +368,53 @@ end
249
368
 
250
369
  private
251
370
 
252
- def __caller_pd_expression__(object)
371
+ def __with_pd_options__(options=nil)
372
+ options ||= {}
373
+ permanent_options = PutsDebuggerer.options
374
+ PutsDebuggerer.options = options.select {|option, _| PutsDebuggerer.options.keys.include?(option)}
375
+ print_engine_options = options.delete_if {|option, _| PutsDebuggerer.options.keys.include?(option)}
376
+ yield print_engine_options
377
+ PutsDebuggerer.options = permanent_options
378
+ end
379
+
380
+ def __build_pd_data__(object, print_engine_options=nil)
381
+ depth = PutsDebuggerer::CALLER_DEPTH_ZERO
382
+ pd_data = {
383
+ announcer: PutsDebuggerer.announcer,
384
+ file: __caller_file__(depth).sub(PutsDebuggerer.app_path.to_s, ''),
385
+ line_number: __caller_line_number__(depth),
386
+ pd_expression: __caller_pd_expression__(depth),
387
+ object: object,
388
+ object_printer: lambda do
389
+ if print_engine_options.to_h.empty?
390
+ send(PutsDebuggerer.print_engine, object)
391
+ else
392
+ send(PutsDebuggerer.print_engine, object, print_engine_options) rescue send(PutsDebuggerer.print_engine, object)
393
+ end
394
+ end
395
+ }
396
+ if PutsDebuggerer.caller?
397
+ start_depth = depth.to_i
398
+ caller_depth = PutsDebuggerer.caller == -1 ? -1 : (start_depth + PutsDebuggerer.caller)
399
+ pd_data[:caller] = caller[start_depth..caller_depth].to_a
400
+ end
401
+ pd_data[:header] = PutsDebuggerer.header if PutsDebuggerer.header?
402
+ pd_data[:footer] = PutsDebuggerer.footer if PutsDebuggerer.footer?
403
+ pd_data
404
+ end
405
+
406
+ def __format_pd_expression__(expression, object)
407
+ # avoid printing expression if it matches object inspection to prevent redundancy
408
+ expression == object.inspect.sub("\n$", '') ? "" : "\n > pd #{expression}\n =>"
409
+ end
410
+
411
+ def __caller_pd_expression__(depth=0)
253
412
  # Caller Source Line Depth 2 = 1 to pd method + 1 to caller
254
- source_line = __caller_source_line__(2)
413
+ source_line = __caller_source_line__(depth+1)
255
414
  source_line = __extract_pd_expression__(source_line)
256
415
  source_line = source_line.gsub(/(^'|'$)/, '"') if source_line.start_with?("'") && source_line.end_with?("'")
257
416
  source_line = source_line.gsub(/(^\(|\)$)/, '') if source_line.start_with?("(") && source_line.end_with?(")")
258
- if source_line == object.inspect.sub("\n$", '')
259
- ""
260
- else
261
- "\n > (#{source_line}).inspect\n =>"
262
- end
417
+ source_line
263
418
  end
264
419
 
265
420
  # Extracts pd source line expression.
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.0
4
+ version: 0.5.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: 2017-03-05 00:00:00.000000000 Z
11
+ date: 2017-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -122,8 +122,16 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: 0.10.0
125
- description: Ruby tools for improved puts debugging, automatically displaying bonus
126
- useful information such as line number and source code
125
+ description: |
126
+ Yes, many of us avoid debuggers like the plague and clamp on to our puts statements like an umbrella in a stormy day. Why not make it official and have puts debugging become its own perfectly legitimate thing?!!
127
+
128
+ And thus, puts_debuggerer was born. A guilt-free puts debugger Ruby gem FTW!
129
+
130
+ In other words, puts_debuggerer is a Ruby library for improved puts debugging, automatically displaying bonus useful information such as source line number and source code.
131
+
132
+ Partially inspired (only partially ;) by this blog post:
133
+ https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html
134
+ (Credit to Tenderlove.)
127
135
  email: andy.am@gmail.com
128
136
  executables: []
129
137
  extensions: []
@@ -157,5 +165,6 @@ rubyforge_project:
157
165
  rubygems_version: 2.6.10
158
166
  signing_key:
159
167
  specification_version: 4
160
- summary: Ruby tools for improved puts debugging
168
+ summary: Ruby library for improved puts debugging, automatically displaying bonus
169
+ useful information such as source line number and source code.
161
170
  test_files: []