puts_debuggerer 0.8.2 → 0.11.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +87 -0
- data/LICENSE.txt +1 -1
- data/README.md +429 -66
- data/VERSION +1 -1
- data/lib/pd.rb +1 -0
- data/lib/puts_debuggerer.rb +157 -278
- data/lib/puts_debuggerer/core_ext/kernel.rb +224 -0
- data/lib/puts_debuggerer/core_ext/logger.rb +3 -0
- data/lib/puts_debuggerer/core_ext/logging/logger.rb +5 -0
- data/lib/puts_debuggerer/run_determiner.rb +109 -0
- data/lib/puts_debuggerer/source_file.rb +32 -0
- metadata +39 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.11.0
|
data/lib/pd.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'puts_debuggerer'
|
data/lib/puts_debuggerer.rb
CHANGED
@@ -1,30 +1,68 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
1
|
+
require 'puts_debuggerer/core_ext/kernel'
|
2
|
+
require 'puts_debuggerer/core_ext/logger'
|
3
|
+
require 'puts_debuggerer/core_ext/logging/logger'
|
4
|
+
require 'puts_debuggerer/run_determiner'
|
5
|
+
require 'puts_debuggerer/source_file'
|
4
6
|
|
5
7
|
module PutsDebuggerer
|
6
|
-
|
7
|
-
|
8
|
+
SOURCE_LINE_COUNT_DEFAULT = 1
|
9
|
+
HEADER_DEFAULT = '>'*80
|
10
|
+
WRAPPER_DEFAULT = '*'*80
|
11
|
+
FOOTER_DEFAULT = '<'*80
|
12
|
+
LOGGER_FORMATTER_DECORATOR = proc { |original_formatter|
|
13
|
+
proc { |severity, datetime, progname, msg|
|
14
|
+
original_formatter.call(severity, datetime, progname, msg.pd_inspect)
|
15
|
+
}
|
16
|
+
}
|
17
|
+
LOGGING_LAYOUT_DECORATOR = proc {|original_layout|
|
18
|
+
original_layout.clone.tap do |layout|
|
19
|
+
layout.singleton_class.class_eval do
|
20
|
+
alias original_format_obj format_obj
|
21
|
+
def format_obj(obj)
|
22
|
+
obj.pdi # alias to pd_inspect
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
}
|
27
|
+
RETURN_DEFAULT = true
|
28
|
+
OBJECT_PRINTER_DEFAULT = lambda do |object, print_engine_options=nil, source_line_count=nil, run_number=nil|
|
29
|
+
lambda do
|
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
|
36
|
+
elsif PutsDebuggerer.print_engine.is_a?(Proc)
|
37
|
+
PutsDebuggerer.print_engine.call(object)
|
38
|
+
else
|
39
|
+
send(PutsDebuggerer.print_engine, object)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
8
43
|
PRINTER_DEFAULT = :puts
|
9
44
|
PRINTER_RAILS = lambda do |output|
|
10
45
|
puts output if Rails.env.test?
|
11
46
|
Rails.logger.debug(output)
|
12
47
|
end
|
13
48
|
PRINT_ENGINE_DEFAULT = :ap
|
14
|
-
PRINTER_MESSAGE_INVALID = 'printer must be a valid global method symbol (e.g. :puts) or lambda/proc receiving a text arg'
|
49
|
+
PRINTER_MESSAGE_INVALID = 'printer must be a valid global method symbol (e.g. :puts), a logger, or a lambda/proc receiving a text arg'
|
15
50
|
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'
|
16
51
|
ANNOUNCER_DEFAULT = '[PD]'
|
17
52
|
FORMATTER_DEFAULT = -> (data) {
|
53
|
+
puts data[:wrapper] if data[:wrapper]
|
18
54
|
puts data[:header] if data[:header]
|
19
|
-
print "#{data[:announcer]} #{data[:file]}
|
55
|
+
print "#{data[:announcer]} #{data[:file]}#{':' if data[:line_number]}#{data[:line_number]}#{" (run:#{data[:run_number]})" if data[:run_number]}#{__format_pd_expression__(data[:pd_expression], data[:object])} "
|
20
56
|
data[:object_printer].call
|
21
57
|
puts data[:caller].map {|l| ' ' + l} unless data[:caller].to_a.empty?
|
22
58
|
puts data[:footer] if data[:footer]
|
59
|
+
puts data[:wrapper] if data[:wrapper]
|
23
60
|
}
|
24
61
|
CALLER_DEPTH_ZERO = 4 #depth includes pd + with_options method + nested block + build_pd_data method
|
25
|
-
|
62
|
+
CALLER_DEPTH_ZERO_OPAL = -1 #depth includes pd + with_options method + nested block + build_pd_data method
|
26
63
|
STACK_TRACE_CALL_LINE_NUMBER_REGEX = /\:(\d+)\:in /
|
27
64
|
STACK_TRACE_CALL_SOURCE_FILE_REGEX = /[ ]*([^:]+)\:\d+\:in /
|
65
|
+
STACK_TRACE_CALL_SOURCE_FILE_REGEX_OPAL = /(http[^\)]+)/
|
28
66
|
|
29
67
|
class << self
|
30
68
|
# Application root path to exclude when printing out file path
|
@@ -46,6 +84,28 @@ module PutsDebuggerer
|
|
46
84
|
@app_path = (path || Rails.root.to_s) rescue nil
|
47
85
|
end
|
48
86
|
|
87
|
+
# Source Line Count.
|
88
|
+
# * Default value is `1`
|
89
|
+
#
|
90
|
+
# Example:
|
91
|
+
#
|
92
|
+
# PutsDebuggerer.source_line_count = 2
|
93
|
+
# pd (true ||
|
94
|
+
# false), source_line_count: 2
|
95
|
+
#
|
96
|
+
# Prints out:
|
97
|
+
#
|
98
|
+
# ********************************************************************************
|
99
|
+
# [PD] /Users/User/example.rb:2
|
100
|
+
# > pd (true ||
|
101
|
+
# false), source_line_count: 2
|
102
|
+
# => "true"
|
103
|
+
attr_reader :source_line_count
|
104
|
+
|
105
|
+
def source_line_count=(value)
|
106
|
+
@source_line_count = value || SOURCE_LINE_COUNT_DEFAULT
|
107
|
+
end
|
108
|
+
|
49
109
|
# Header to include at the top of every print out.
|
50
110
|
# * Default value is `nil`
|
51
111
|
# * Value `true` enables header as `'*'*80`
|
@@ -65,19 +125,24 @@ module PutsDebuggerer
|
|
65
125
|
# => "1"
|
66
126
|
attr_reader :header
|
67
127
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
128
|
+
# Wrapper to include at the top and bottom of every print out (both header and footer).
|
129
|
+
# * Default value is `nil`
|
130
|
+
# * Value `true` enables wrapper as `'*'*80`
|
131
|
+
# * Value `false`, `nil`, or empty string disables wrapper
|
132
|
+
# * Any other string value gets set as a custom wrapper
|
133
|
+
#
|
134
|
+
# Example:
|
135
|
+
#
|
136
|
+
# PutsDebuggerer.wrapper = true
|
137
|
+
# pd (x=1)
|
138
|
+
#
|
139
|
+
# Prints out:
|
140
|
+
#
|
141
|
+
# [PD] /Users/User/example.rb:2
|
142
|
+
# > pd x=1
|
143
|
+
# => "1"
|
144
|
+
# ********************************************************************************
|
145
|
+
attr_reader :wrapper
|
81
146
|
|
82
147
|
# Footer to include at the bottom of every print out.
|
83
148
|
# * Default value is `nil`
|
@@ -97,24 +162,27 @@ module PutsDebuggerer
|
|
97
162
|
# => "1"
|
98
163
|
# ********************************************************************************
|
99
164
|
attr_reader :footer
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
165
|
+
|
166
|
+
['header', 'footer', 'wrapper'].each do |boundary_option|
|
167
|
+
define_method("#{boundary_option}=") do |value|
|
168
|
+
if value.equal?(true)
|
169
|
+
instance_variable_set(:"@#{boundary_option}", const_get(:"#{boundary_option.upcase}_DEFAULT"))
|
170
|
+
elsif value == ''
|
171
|
+
instance_variable_set(:"@#{boundary_option}", nil)
|
172
|
+
else
|
173
|
+
instance_variable_set(:"@#{boundary_option}", value)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
define_method("#{boundary_option}?") do
|
178
|
+
!!instance_variable_get(:"@#{boundary_option}")
|
108
179
|
end
|
109
180
|
end
|
110
181
|
|
111
|
-
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
# Printer is a global method symbol or lambda expression to use in printing to the user.
|
116
|
-
# Examples of global methods are `:puts` and `:print`.
|
182
|
+
# Printer is a global method symbol, lambda expression, or logger to use in printing to the user.
|
183
|
+
# Examples of a global method are `:puts` and `:print`.
|
117
184
|
# An example of a lambda expression is `lambda {|output| Rails.logger.ap(output)}`
|
185
|
+
# Examples of a logger are a Ruby `Logger` instance or `Logging::Logger` instance
|
118
186
|
#
|
119
187
|
# Defaults to `:puts`
|
120
188
|
# In Rails, it defaults to: `lambda {|output| Rails.logger.ap(output)}`
|
@@ -135,17 +203,37 @@ module PutsDebuggerer
|
|
135
203
|
|
136
204
|
def printer=(printer)
|
137
205
|
if printer.nil?
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
206
|
+
@printer = printer_default
|
207
|
+
elsif printer.is_a?(Logger)
|
208
|
+
@printer = printer
|
209
|
+
@logger_original_formatter = printer.formatter || Logger::Formatter.new
|
210
|
+
printer.formatter = LOGGER_FORMATTER_DECORATOR.call(@logger_original_formatter)
|
211
|
+
elsif printer.is_a?(Logging::Logger)
|
212
|
+
@printer = printer
|
213
|
+
@logging_original_layouts = printer.appenders.reduce({}) do |hash, appender|
|
214
|
+
hash.merge(appender => appender.layout)
|
215
|
+
end
|
216
|
+
printer.appenders.each do |appender|
|
217
|
+
appender.layout = LOGGING_LAYOUT_DECORATOR.call(appender.layout)
|
142
218
|
end
|
143
|
-
elsif printer.is_a?(Proc)
|
219
|
+
elsif printer == false || printer.is_a?(Proc) || printer.respond_to?(:log) # a logger
|
144
220
|
@printer = printer
|
145
221
|
else
|
146
222
|
@printer = method(printer).name rescue raise(PRINTER_MESSAGE_INVALID)
|
147
223
|
end
|
148
224
|
end
|
225
|
+
|
226
|
+
def printer_default
|
227
|
+
Object.const_defined?(:Rails) ? PRINTER_RAILS : PRINTER_DEFAULT
|
228
|
+
end
|
229
|
+
|
230
|
+
# Logger original formatter before it was decorated with PutsDebuggerer::LOGGER_FORMATTER_DECORATOR
|
231
|
+
# upon setting the logger as a printer.
|
232
|
+
attr_reader :logger_original_formatter
|
233
|
+
|
234
|
+
# Logging library original layouts before being decorated with PutsDebuggerer::LOGGING_LAYOUT_DECORATOR
|
235
|
+
# upon setting the Logging library logger as a printer.
|
236
|
+
attr_reader :logging_original_layouts
|
149
237
|
|
150
238
|
# Print engine is similar to `printer`, except it is focused on the scope of formatting
|
151
239
|
# the data object being printed (excluding metadata such as file name, line number,
|
@@ -170,17 +258,25 @@ module PutsDebuggerer
|
|
170
258
|
# > pd array
|
171
259
|
# => [1, [2, 3]]
|
172
260
|
# ]
|
173
|
-
|
261
|
+
def print_engine
|
262
|
+
if @print_engine.nil?
|
263
|
+
require 'awesome_print' if RUBY_ENGINE != 'opal'
|
264
|
+
@print_engine = print_engine_default
|
265
|
+
end
|
266
|
+
@print_engine
|
267
|
+
end
|
174
268
|
|
175
269
|
def print_engine=(engine)
|
176
|
-
if engine.nil?
|
177
|
-
@print_engine = PRINT_ENGINE_DEFAULT
|
178
|
-
elsif engine.is_a?(Proc)
|
270
|
+
if engine.is_a?(Proc) || engine.nil?
|
179
271
|
@print_engine = engine
|
180
272
|
else
|
181
273
|
@print_engine = method(engine).name rescue raise(PRINT_ENGINE_MESSAGE_INVALID)
|
182
274
|
end
|
183
275
|
end
|
276
|
+
|
277
|
+
def print_engine_default
|
278
|
+
Object.const_defined?(:AwesomePrint) ? PRINT_ENGINE_DEFAULT : :p
|
279
|
+
end
|
184
280
|
|
185
281
|
# Announcer (e.g. [PD]) to announce every print out with (default: "[PD]")
|
186
282
|
#
|
@@ -206,12 +302,14 @@ module PutsDebuggerer
|
|
206
302
|
# * :announcer (string)
|
207
303
|
# * :caller (array)
|
208
304
|
# * :file (string)
|
305
|
+
# * :wrapper (string)
|
209
306
|
# * :footer (string)
|
210
307
|
# * :header (string)
|
211
308
|
# * :line_number (string)
|
212
309
|
# * :pd_expression (string)
|
213
310
|
# * :object (object)
|
214
311
|
# * :object_printer (proc)
|
312
|
+
# * :source_line_count (integer)
|
215
313
|
#
|
216
314
|
# NOTE: data for :object_printer is not a string, yet a proc that must
|
217
315
|
# be called to output value. It is a proc as it automatically handles usage
|
@@ -289,9 +387,11 @@ module PutsDebuggerer
|
|
289
387
|
def options
|
290
388
|
{
|
291
389
|
header: header,
|
390
|
+
wrapper: wrapper,
|
292
391
|
footer: footer,
|
293
392
|
printer: printer,
|
294
393
|
print_engine: print_engine,
|
394
|
+
source_line_count: source_line_count,
|
295
395
|
app_path: app_path,
|
296
396
|
announcer: announcer,
|
297
397
|
formatter: formatter,
|
@@ -368,44 +468,25 @@ module PutsDebuggerer
|
|
368
468
|
!!@run_at
|
369
469
|
end
|
370
470
|
|
371
|
-
|
372
|
-
|
373
|
-
def run_at_global_number=(value)
|
374
|
-
@run_at_global_number = value
|
375
|
-
end
|
376
|
-
|
377
|
-
def init_run_at_global_number
|
378
|
-
@run_at_global_number = 1
|
379
|
-
end
|
380
|
-
|
381
|
-
def increment_run_at_global_number
|
382
|
-
@run_at_global_number += 1
|
383
|
-
end
|
384
|
-
|
385
|
-
def reset_run_at_global_number
|
386
|
-
@run_at_global_number = nil
|
387
|
-
end
|
388
|
-
|
389
|
-
def run_at_number(object, run_at)
|
390
|
-
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)
|
391
473
|
end
|
392
474
|
|
393
|
-
def
|
394
|
-
|
475
|
+
def determine_object(objects)
|
476
|
+
objects.compact.size > 1 ? objects : objects.first
|
395
477
|
end
|
396
478
|
|
397
|
-
def
|
398
|
-
|
479
|
+
def determine_run_at(options)
|
480
|
+
((options && options[:run_at]) || PutsDebuggerer.run_at)
|
399
481
|
end
|
400
482
|
|
401
|
-
def
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
483
|
+
def determine_printer(options)
|
484
|
+
if options && options.has_key?(:printer)
|
485
|
+
options[:printer]
|
486
|
+
else
|
487
|
+
PutsDebuggerer.printer
|
488
|
+
end
|
407
489
|
end
|
408
|
-
|
409
490
|
end
|
410
491
|
end
|
411
492
|
|
@@ -417,206 +498,4 @@ PutsDebuggerer.formatter = nil
|
|
417
498
|
PutsDebuggerer.app_path = nil
|
418
499
|
PutsDebuggerer.caller = nil
|
419
500
|
PutsDebuggerer.run_at = nil
|
420
|
-
|
421
|
-
# Prints object with bonus info such as file name, line number and source
|
422
|
-
# expression. Optionally prints out header and footer.
|
423
|
-
# Lookup PutsDebuggerer attributes for more details about configuration options.
|
424
|
-
#
|
425
|
-
# Simply invoke global `pd` method anywhere you'd like to see line number and source code with output.
|
426
|
-
# If the argument is a pure string, the print out is simplified by not showing duplicate source.
|
427
|
-
#
|
428
|
-
# Quickly locate printed lines using Find feature (e.g. CTRL+F) by looking for:
|
429
|
-
# * \[PD\]
|
430
|
-
# * file:line_number
|
431
|
-
# * ruby expression.
|
432
|
-
#
|
433
|
-
# This gives you the added benefit of easily removing your pd statements later on from the code.
|
434
|
-
#
|
435
|
-
# Happy puts_debuggerering!
|
436
|
-
#
|
437
|
-
# Example Code:
|
438
|
-
#
|
439
|
-
# # /Users/User/finance_calculator_app/pd_test.rb # line 1
|
440
|
-
# bug = 'beattle' # line 2
|
441
|
-
# pd "Show me the source of the bug: #{bug}" # line 3
|
442
|
-
# pd 'What line number am I?' # line 4
|
443
|
-
#
|
444
|
-
# Example Printout:
|
445
|
-
#
|
446
|
-
# [PD] /Users/User/finance_calculator_app/pd_test.rb:3
|
447
|
-
# > pd "Show me the source of the bug: #{bug}"
|
448
|
-
# => "Show me the source of the bug: beattle"
|
449
|
-
# [PD] /Users/User/finance_calculator_app/pd_test.rb:4 "What line number am I?"
|
450
|
-
def pd(object, options=nil)
|
451
|
-
run_at = ((options && options[:run_at]) || PutsDebuggerer.run_at)
|
452
|
-
|
453
|
-
if __run_pd__(object, run_at)
|
454
|
-
__with_pd_options__(options) do |print_engine_options|
|
455
|
-
formatter_pd_data = __build_pd_data__(object, print_engine_options) #depth adds build method
|
456
|
-
stdout = $stdout
|
457
|
-
$stdout = sio = StringIO.new
|
458
|
-
PutsDebuggerer.formatter.call(formatter_pd_data)
|
459
|
-
$stdout = stdout
|
460
|
-
if PutsDebuggerer.printer.is_a?(Proc)
|
461
|
-
PutsDebuggerer.printer.call(sio.string)
|
462
|
-
else
|
463
|
-
send(PutsDebuggerer.send(:printer), sio.string)
|
464
|
-
end
|
465
|
-
end
|
466
|
-
end
|
467
|
-
|
468
|
-
object
|
469
|
-
end
|
470
|
-
|
471
|
-
def __run_pd__(object, run_at)
|
472
|
-
run_pd = false
|
473
|
-
if run_at.nil?
|
474
|
-
run_pd = true
|
475
|
-
else
|
476
|
-
if PutsDebuggerer.run_at?
|
477
|
-
if PutsDebuggerer.run_at_global_number.nil?
|
478
|
-
PutsDebuggerer.init_run_at_global_number
|
479
|
-
else
|
480
|
-
PutsDebuggerer.increment_run_at_global_number
|
481
|
-
end
|
482
|
-
run_number = PutsDebuggerer.run_at_global_number
|
483
|
-
else
|
484
|
-
if PutsDebuggerer.run_at_number(object, run_at).nil?
|
485
|
-
PutsDebuggerer.init_run_at_number(object, run_at)
|
486
|
-
else
|
487
|
-
PutsDebuggerer.increment_run_at_number(object, run_at)
|
488
|
-
end
|
489
|
-
run_number = PutsDebuggerer.run_at_number(object, run_at)
|
490
|
-
end
|
491
|
-
if run_at.is_a?(Integer)
|
492
|
-
run_pd = true if run_at == run_number
|
493
|
-
elsif run_at.is_a?(Array)
|
494
|
-
run_pd = true if run_at.include?(run_number)
|
495
|
-
elsif run_at.is_a?(Range)
|
496
|
-
run_pd = true if run_at.cover?(run_number) || (run_at.end == -1 && run_number >= run_at.begin)
|
497
|
-
end
|
498
|
-
end
|
499
|
-
run_pd
|
500
|
-
end
|
501
|
-
|
502
|
-
# Provides caller line number starting 1 level above caller of
|
503
|
-
# this method.
|
504
|
-
#
|
505
|
-
# Example:
|
506
|
-
#
|
507
|
-
# # lib/example.rb # line 1
|
508
|
-
# puts "Print out __caller_line_number__" # line 2
|
509
|
-
# puts __caller_line_number__ # line 3
|
510
|
-
#
|
511
|
-
# prints out `3`
|
512
|
-
def __caller_line_number__(caller_depth=0)
|
513
|
-
caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_LINE_NUMBER_REGEX, 1].to_i
|
514
|
-
end
|
515
|
-
|
516
|
-
# Provides caller file starting 1 level above caller of
|
517
|
-
# this method.
|
518
|
-
#
|
519
|
-
# Example:
|
520
|
-
#
|
521
|
-
# # File Name: lib/example.rb
|
522
|
-
# puts __caller_file__
|
523
|
-
#
|
524
|
-
# prints out `lib/example.rb`
|
525
|
-
def __caller_file__(caller_depth=0)
|
526
|
-
caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_SOURCE_FILE_REGEX, 1]
|
527
|
-
end
|
528
|
-
|
529
|
-
|
530
|
-
# Provides caller source line starting 1 level above caller of
|
531
|
-
# this method.
|
532
|
-
#
|
533
|
-
# Example:
|
534
|
-
#
|
535
|
-
# puts __caller_source_line__
|
536
|
-
#
|
537
|
-
# prints out `puts __caller_source_line__`
|
538
|
-
def __caller_source_line__(caller_depth=0, source_file=nil, source_line_number=nil)
|
539
|
-
source_line_number ||= __caller_line_number__(caller_depth+1)
|
540
|
-
source_file ||= __caller_file__(caller_depth+1)
|
541
|
-
source_line = nil
|
542
|
-
if source_file == '(irb)'
|
543
|
-
source_line = conf.io.line(source_line_number)
|
544
|
-
else
|
545
|
-
f = File.new(source_file)
|
546
|
-
source_line = ''
|
547
|
-
done = false
|
548
|
-
f.each_line do |line|
|
549
|
-
if !done && f.lineno == source_line_number
|
550
|
-
source_line << line
|
551
|
-
done = true if Ripper.sexp_raw(source_line) || source_line.include?('%>') #the last condition is for erb support (unofficial)
|
552
|
-
source_line_number+=1
|
553
|
-
end
|
554
|
-
end
|
555
|
-
end
|
556
|
-
source_line
|
557
|
-
end
|
558
|
-
|
559
|
-
private
|
560
|
-
|
561
|
-
def __with_pd_options__(options=nil)
|
562
|
-
options ||= {}
|
563
|
-
permanent_options = PutsDebuggerer.options
|
564
|
-
PutsDebuggerer.options = options.select {|option, _| PutsDebuggerer.options.keys.include?(option)}
|
565
|
-
print_engine_options = options.delete_if {|option, _| PutsDebuggerer.options.keys.include?(option)}
|
566
|
-
yield print_engine_options
|
567
|
-
PutsDebuggerer.options = permanent_options
|
568
|
-
end
|
569
|
-
|
570
|
-
def __build_pd_data__(object, print_engine_options=nil)
|
571
|
-
depth = PutsDebuggerer::CALLER_DEPTH_ZERO
|
572
|
-
pd_data = {
|
573
|
-
announcer: PutsDebuggerer.announcer,
|
574
|
-
file: __caller_file__(depth).sub(PutsDebuggerer.app_path.to_s, ''),
|
575
|
-
line_number: __caller_line_number__(depth),
|
576
|
-
pd_expression: __caller_pd_expression__(depth),
|
577
|
-
object: object,
|
578
|
-
object_printer: lambda do
|
579
|
-
if PutsDebuggerer.print_engine.is_a?(Proc)
|
580
|
-
PutsDebuggerer.print_engine.call(object)
|
581
|
-
else
|
582
|
-
if print_engine_options.to_h.empty?
|
583
|
-
send(PutsDebuggerer.print_engine, object)
|
584
|
-
else
|
585
|
-
send(PutsDebuggerer.print_engine, object, print_engine_options) rescue send(PutsDebuggerer.print_engine, object)
|
586
|
-
end
|
587
|
-
end
|
588
|
-
end
|
589
|
-
}
|
590
|
-
if PutsDebuggerer.caller?
|
591
|
-
start_depth = depth.to_i
|
592
|
-
caller_depth = PutsDebuggerer.caller == -1 ? -1 : (start_depth + PutsDebuggerer.caller)
|
593
|
-
pd_data[:caller] = caller[start_depth..caller_depth].to_a
|
594
|
-
end
|
595
|
-
pd_data[:header] = PutsDebuggerer.header if PutsDebuggerer.header?
|
596
|
-
pd_data[:footer] = PutsDebuggerer.footer if PutsDebuggerer.footer?
|
597
|
-
pd_data
|
598
|
-
end
|
599
|
-
|
600
|
-
def __format_pd_expression__(expression, object)
|
601
|
-
"\n > #{expression}\n =>"
|
602
|
-
end
|
603
|
-
|
604
|
-
def __caller_pd_expression__(depth=0)
|
605
|
-
# Caller Source Line Depth 2 = 1 to pd method + 1 to caller
|
606
|
-
source_line = __caller_source_line__(depth+1)
|
607
|
-
source_line = __extract_pd_expression__(source_line)
|
608
|
-
source_line = source_line.gsub(/(^'|'$)/, '"') if source_line.start_with?("'") && source_line.end_with?("'")
|
609
|
-
source_line = source_line.gsub(/(^\(|\)$)/, '') if source_line.start_with?("(") && source_line.end_with?(")")
|
610
|
-
source_line
|
611
|
-
end
|
612
|
-
|
613
|
-
# Extracts pd source line expression.
|
614
|
-
#
|
615
|
-
# Example:
|
616
|
-
#
|
617
|
-
# __extract_pd_expression__("pd (x=1)")
|
618
|
-
#
|
619
|
-
# outputs `(x=1)`
|
620
|
-
def __extract_pd_expression__(source_line)
|
621
|
-
source_line.strip
|
622
|
-
end
|
501
|
+
PutsDebuggerer.source_line_count = nil
|