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