puts_debuggerer 0.9.0 → 0.12.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 +30 -0
- data/README.md +360 -59
- data/VERSION +1 -1
- data/lib/pd.rb +1 -0
- data/lib/puts_debuggerer.rb +116 -305
- 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 +32 -12
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.12.0
|
data/lib/pd.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'puts_debuggerer'
|
data/lib/puts_debuggerer.rb
CHANGED
@@ -1,33 +1,69 @@
|
|
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
|
5
8
|
SOURCE_LINE_COUNT_DEFAULT = 1
|
6
|
-
HEADER_DEFAULT = '
|
9
|
+
HEADER_DEFAULT = '>'*80
|
7
10
|
WRAPPER_DEFAULT = '*'*80
|
8
|
-
FOOTER_DEFAULT = '
|
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
|
9
43
|
PRINTER_DEFAULT = :puts
|
10
44
|
PRINTER_RAILS = lambda do |output|
|
11
45
|
puts output if Rails.env.test?
|
12
46
|
Rails.logger.debug(output)
|
13
47
|
end
|
14
48
|
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'
|
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'
|
16
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'
|
17
51
|
ANNOUNCER_DEFAULT = '[PD]'
|
18
52
|
FORMATTER_DEFAULT = -> (data) {
|
19
53
|
puts data[:wrapper] if data[:wrapper]
|
20
54
|
puts data[:header] if data[:header]
|
21
|
-
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])} "
|
22
56
|
data[:object_printer].call
|
23
57
|
puts data[:caller].map {|l| ' ' + l} unless data[:caller].to_a.empty?
|
24
58
|
puts data[:footer] if data[:footer]
|
25
59
|
puts data[:wrapper] if data[:wrapper]
|
26
60
|
}
|
27
61
|
CALLER_DEPTH_ZERO = 4 #depth includes pd + with_options method + nested block + build_pd_data method
|
28
|
-
|
62
|
+
CALLER_DEPTH_ZERO_OPAL = -1 #depth includes pd + with_options method + nested block + build_pd_data method
|
29
63
|
STACK_TRACE_CALL_LINE_NUMBER_REGEX = /\:(\d+)\:in /
|
30
64
|
STACK_TRACE_CALL_SOURCE_FILE_REGEX = /[ ]*([^:]+)\:\d+\:in /
|
65
|
+
STACK_TRACE_CALL_SOURCE_FILE_REGEX_OPAL = /(http[^\)]+)/
|
66
|
+
OPTIONS = [:app_path, :source_line_count, :header, :wrapper, :footer, :printer, :print_engine, :announcer, :formatter, :caller, :run_at]
|
31
67
|
|
32
68
|
class << self
|
33
69
|
# Application root path to exclude when printing out file path
|
@@ -90,20 +126,6 @@ module PutsDebuggerer
|
|
90
126
|
# => "1"
|
91
127
|
attr_reader :header
|
92
128
|
|
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
129
|
# Wrapper to include at the top and bottom of every print out (both header and footer).
|
108
130
|
# * Default value is `nil`
|
109
131
|
# * Value `true` enables wrapper as `'*'*80`
|
@@ -123,20 +145,6 @@ module PutsDebuggerer
|
|
123
145
|
# ********************************************************************************
|
124
146
|
attr_reader :wrapper
|
125
147
|
|
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
148
|
# Footer to include at the bottom of every print out.
|
141
149
|
# * Default value is `nil`
|
142
150
|
# * Value `true` enables footer as `'*'*80`
|
@@ -155,24 +163,27 @@ module PutsDebuggerer
|
|
155
163
|
# => "1"
|
156
164
|
# ********************************************************************************
|
157
165
|
attr_reader :footer
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
+
|
167
|
+
['header', 'footer', 'wrapper'].each do |boundary_option|
|
168
|
+
define_method("#{boundary_option}=") do |value|
|
169
|
+
if value.equal?(true)
|
170
|
+
instance_variable_set(:"@#{boundary_option}", const_get(:"#{boundary_option.upcase}_DEFAULT"))
|
171
|
+
elsif value == ''
|
172
|
+
instance_variable_set(:"@#{boundary_option}", nil)
|
173
|
+
else
|
174
|
+
instance_variable_set(:"@#{boundary_option}", value)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
define_method("#{boundary_option}?") do
|
179
|
+
!!instance_variable_get(:"@#{boundary_option}")
|
166
180
|
end
|
167
181
|
end
|
168
182
|
|
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`.
|
183
|
+
# Printer is a global method symbol, lambda expression, or logger to use in printing to the user.
|
184
|
+
# Examples of a global method are `:puts` and `:print`.
|
175
185
|
# An example of a lambda expression is `lambda {|output| Rails.logger.ap(output)}`
|
186
|
+
# Examples of a logger are a Ruby `Logger` instance or `Logging::Logger` instance
|
176
187
|
#
|
177
188
|
# Defaults to `:puts`
|
178
189
|
# In Rails, it defaults to: `lambda {|output| Rails.logger.ap(output)}`
|
@@ -193,17 +204,37 @@ module PutsDebuggerer
|
|
193
204
|
|
194
205
|
def printer=(printer)
|
195
206
|
if printer.nil?
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
207
|
+
@printer = printer_default
|
208
|
+
elsif printer.is_a?(Logger)
|
209
|
+
@printer = printer
|
210
|
+
@logger_original_formatter = printer.formatter || Logger::Formatter.new
|
211
|
+
printer.formatter = LOGGER_FORMATTER_DECORATOR.call(@logger_original_formatter)
|
212
|
+
elsif printer.is_a?(Logging::Logger)
|
213
|
+
@printer = printer
|
214
|
+
@logging_original_layouts = printer.appenders.reduce({}) do |hash, appender|
|
215
|
+
hash.merge(appender => appender.layout)
|
200
216
|
end
|
201
|
-
|
217
|
+
printer.appenders.each do |appender|
|
218
|
+
appender.layout = LOGGING_LAYOUT_DECORATOR.call(appender.layout)
|
219
|
+
end
|
220
|
+
elsif printer == false || printer.is_a?(Proc) || printer.respond_to?(:log) # a logger
|
202
221
|
@printer = printer
|
203
222
|
else
|
204
223
|
@printer = method(printer).name rescue raise(PRINTER_MESSAGE_INVALID)
|
205
224
|
end
|
206
225
|
end
|
226
|
+
|
227
|
+
def printer_default
|
228
|
+
Object.const_defined?(:Rails) ? PRINTER_RAILS : PRINTER_DEFAULT
|
229
|
+
end
|
230
|
+
|
231
|
+
# Logger original formatter before it was decorated with PutsDebuggerer::LOGGER_FORMATTER_DECORATOR
|
232
|
+
# upon setting the logger as a printer.
|
233
|
+
attr_reader :logger_original_formatter
|
234
|
+
|
235
|
+
# Logging library original layouts before being decorated with PutsDebuggerer::LOGGING_LAYOUT_DECORATOR
|
236
|
+
# upon setting the Logging library logger as a printer.
|
237
|
+
attr_reader :logging_original_layouts
|
207
238
|
|
208
239
|
# Print engine is similar to `printer`, except it is focused on the scope of formatting
|
209
240
|
# the data object being printed (excluding metadata such as file name, line number,
|
@@ -228,17 +259,25 @@ module PutsDebuggerer
|
|
228
259
|
# > pd array
|
229
260
|
# => [1, [2, 3]]
|
230
261
|
# ]
|
231
|
-
|
262
|
+
def print_engine
|
263
|
+
if @print_engine.nil?
|
264
|
+
require 'awesome_print' if RUBY_ENGINE != 'opal'
|
265
|
+
@print_engine = print_engine_default
|
266
|
+
end
|
267
|
+
@print_engine
|
268
|
+
end
|
232
269
|
|
233
270
|
def print_engine=(engine)
|
234
|
-
if engine.nil?
|
235
|
-
@print_engine = Object.const_defined?(:AwesomePrint) ? PRINT_ENGINE_DEFAULT : :p
|
236
|
-
elsif engine.is_a?(Proc)
|
271
|
+
if engine.is_a?(Proc) || engine.nil?
|
237
272
|
@print_engine = engine
|
238
273
|
else
|
239
274
|
@print_engine = method(engine).name rescue raise(PRINT_ENGINE_MESSAGE_INVALID)
|
240
275
|
end
|
241
276
|
end
|
277
|
+
|
278
|
+
def print_engine_default
|
279
|
+
Object.const_defined?(:AwesomePrint) ? PRINT_ENGINE_DEFAULT : :p
|
280
|
+
end
|
242
281
|
|
243
282
|
# Announcer (e.g. [PD]) to announce every print out with (default: "[PD]")
|
244
283
|
#
|
@@ -430,44 +469,32 @@ module PutsDebuggerer
|
|
430
469
|
!!@run_at
|
431
470
|
end
|
432
471
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
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]]
|
453
|
-
end
|
454
|
-
|
455
|
-
def init_run_at_number(object, run_at)
|
456
|
-
PutsDebuggerer::OBJECT_RUN_AT[[object,run_at]] = 1
|
472
|
+
def determine_options(objects)
|
473
|
+
if objects.size > 1 && objects.last.is_a?(Hash)
|
474
|
+
objects.delete_at(-1)
|
475
|
+
elsif objects.size == 1 && objects.first.is_a?(Hash)
|
476
|
+
hash = objects.first
|
477
|
+
hash.slice(*OPTIONS).tap do
|
478
|
+
hash.delete_if {|option| OPTIONS.include?(option)}
|
479
|
+
end
|
480
|
+
end
|
457
481
|
end
|
458
482
|
|
459
|
-
def
|
460
|
-
|
483
|
+
def determine_object(objects)
|
484
|
+
objects.compact.size > 1 ? objects : objects.first
|
461
485
|
end
|
462
486
|
|
463
|
-
def
|
464
|
-
|
487
|
+
def determine_run_at(options)
|
488
|
+
((options && options[:run_at]) || PutsDebuggerer.run_at)
|
465
489
|
end
|
466
490
|
|
467
|
-
def
|
468
|
-
|
491
|
+
def determine_printer(options)
|
492
|
+
if options && options.has_key?(:printer)
|
493
|
+
options[:printer]
|
494
|
+
else
|
495
|
+
PutsDebuggerer.printer
|
496
|
+
end
|
469
497
|
end
|
470
|
-
|
471
498
|
end
|
472
499
|
end
|
473
500
|
|
@@ -480,219 +507,3 @@ PutsDebuggerer.app_path = nil
|
|
480
507
|
PutsDebuggerer.caller = nil
|
481
508
|
PutsDebuggerer.run_at = nil
|
482
509
|
PutsDebuggerer.source_line_count = nil
|
483
|
-
|
484
|
-
# Prints object with bonus info such as file name, line number and source
|
485
|
-
# expression. Optionally prints out header and footer.
|
486
|
-
# Lookup PutsDebuggerer attributes for more details about configuration options.
|
487
|
-
#
|
488
|
-
# Simply invoke global `pd` method anywhere you'd like to see line number and source code with output.
|
489
|
-
# If the argument is a pure string, the print out is simplified by not showing duplicate source.
|
490
|
-
#
|
491
|
-
# Quickly locate printed lines using Find feature (e.g. CTRL+F) by looking for:
|
492
|
-
# * \[PD\]
|
493
|
-
# * file:line_number
|
494
|
-
# * ruby expression.
|
495
|
-
#
|
496
|
-
# This gives you the added benefit of easily removing your pd statements later on from the code.
|
497
|
-
#
|
498
|
-
# Happy puts_debuggerering!
|
499
|
-
#
|
500
|
-
# Example Code:
|
501
|
-
#
|
502
|
-
# # /Users/User/finance_calculator_app/pd_test.rb # line 1
|
503
|
-
# bug = 'beattle' # line 2
|
504
|
-
# pd "Show me the source of the bug: #{bug}" # line 3
|
505
|
-
# pd 'What line number am I?' # line 4
|
506
|
-
#
|
507
|
-
# Example Printout:
|
508
|
-
#
|
509
|
-
# [PD] /Users/User/finance_calculator_app/pd_test.rb:3
|
510
|
-
# > pd "Show me the source of the bug: #{bug}"
|
511
|
-
# => "Show me the source of the bug: beattle"
|
512
|
-
# [PD] /Users/User/finance_calculator_app/pd_test.rb:4 "What line number am I?"
|
513
|
-
def pd(*objects)
|
514
|
-
options = objects.delete_at(-1) if objects.size > 1 && objects.last.is_a?(Hash)
|
515
|
-
object = objects.compact.size > 1 ? objects : objects.first
|
516
|
-
run_at = ((options && options[:run_at]) || PutsDebuggerer.run_at)
|
517
|
-
|
518
|
-
if __run_pd__(object, run_at)
|
519
|
-
__with_pd_options__(options) do |print_engine_options|
|
520
|
-
run_number = PutsDebuggerer.run_at_global_number || PutsDebuggerer.run_at_number(object, run_at)
|
521
|
-
formatter_pd_data = __build_pd_data__(object, print_engine_options, PutsDebuggerer.source_line_count, run_number) #depth adds build method
|
522
|
-
stdout = $stdout
|
523
|
-
$stdout = sio = StringIO.new
|
524
|
-
PutsDebuggerer.formatter.call(formatter_pd_data)
|
525
|
-
$stdout = stdout
|
526
|
-
if PutsDebuggerer.printer.is_a?(Proc)
|
527
|
-
PutsDebuggerer.printer.call(sio.string)
|
528
|
-
else
|
529
|
-
send(PutsDebuggerer.send(:printer), sio.string)
|
530
|
-
end
|
531
|
-
end
|
532
|
-
end
|
533
|
-
|
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
|
566
|
-
end
|
567
|
-
|
568
|
-
# Provides caller line number starting 1 level above caller of
|
569
|
-
# this method.
|
570
|
-
#
|
571
|
-
# Example:
|
572
|
-
#
|
573
|
-
# # lib/example.rb # line 1
|
574
|
-
# puts "Print out __caller_line_number__" # line 2
|
575
|
-
# puts __caller_line_number__ # line 3
|
576
|
-
#
|
577
|
-
# prints out `3`
|
578
|
-
def __caller_line_number__(caller_depth=0)
|
579
|
-
caller[caller_depth] && caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_LINE_NUMBER_REGEX, 1].to_i
|
580
|
-
end
|
581
|
-
|
582
|
-
# Provides caller file starting 1 level above caller of
|
583
|
-
# this method.
|
584
|
-
#
|
585
|
-
# Example:
|
586
|
-
#
|
587
|
-
# # File Name: lib/example.rb
|
588
|
-
# puts __caller_file__
|
589
|
-
#
|
590
|
-
# prints out `lib/example.rb`
|
591
|
-
def __caller_file__(caller_depth=0)
|
592
|
-
caller[caller_depth] && caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_SOURCE_FILE_REGEX, 1]
|
593
|
-
end
|
594
|
-
|
595
|
-
|
596
|
-
# Provides caller source line starting 1 level above caller of
|
597
|
-
# this method.
|
598
|
-
#
|
599
|
-
# Example:
|
600
|
-
#
|
601
|
-
# puts __caller_source_line__
|
602
|
-
#
|
603
|
-
# prints out `puts __caller_source_line__`
|
604
|
-
def __caller_source_line__(caller_depth=0, source_line_count=nil, source_file=nil, source_line_number=nil)
|
605
|
-
source_line_number ||= __caller_line_number__(caller_depth+1)
|
606
|
-
source_file ||= __caller_file__(caller_depth+1)
|
607
|
-
source_line = ''
|
608
|
-
if source_file == '(irb)'
|
609
|
-
source_line = conf.io.line(source_line_number)
|
610
|
-
else
|
611
|
-
f = File.new(source_file)
|
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
|
627
|
-
end
|
628
|
-
source_line
|
629
|
-
end
|
630
|
-
|
631
|
-
private
|
632
|
-
|
633
|
-
def __with_pd_options__(options=nil)
|
634
|
-
options ||= {}
|
635
|
-
permanent_options = PutsDebuggerer.options
|
636
|
-
PutsDebuggerer.options = options.select {|option, _| PutsDebuggerer.options.keys.include?(option)}
|
637
|
-
print_engine_options = options.delete_if {|option, _| PutsDebuggerer.options.keys.include?(option)}
|
638
|
-
yield print_engine_options
|
639
|
-
PutsDebuggerer.options = permanent_options
|
640
|
-
end
|
641
|
-
|
642
|
-
def __build_pd_data__(object, print_engine_options=nil, source_line_count=nil, run_number=nil)
|
643
|
-
depth = PutsDebuggerer::CALLER_DEPTH_ZERO
|
644
|
-
pd_data = {
|
645
|
-
announcer: PutsDebuggerer.announcer,
|
646
|
-
file: __caller_file__(depth)&.sub(PutsDebuggerer.app_path.to_s, ''),
|
647
|
-
line_number: __caller_line_number__(depth),
|
648
|
-
pd_expression: __caller_pd_expression__(depth, source_line_count),
|
649
|
-
run_number: run_number,
|
650
|
-
object: object,
|
651
|
-
object_printer: lambda do
|
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
|
664
|
-
}
|
665
|
-
if PutsDebuggerer.caller?
|
666
|
-
start_depth = depth.to_i
|
667
|
-
caller_depth = PutsDebuggerer.caller == -1 ? -1 : (start_depth + PutsDebuggerer.caller)
|
668
|
-
pd_data[:caller] = caller[start_depth..caller_depth].to_a
|
669
|
-
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
|
-
pd_data
|
674
|
-
end
|
675
|
-
|
676
|
-
def __format_pd_expression__(expression, object)
|
677
|
-
"\n > #{expression}\n =>"
|
678
|
-
end
|
679
|
-
|
680
|
-
def __caller_pd_expression__(depth=0, source_line_count=nil)
|
681
|
-
# Caller Source Line Depth 2 = 1 to pd method + 1 to caller
|
682
|
-
source_line = __caller_source_line__(depth+1, source_line_count)
|
683
|
-
source_line = __extract_pd_expression__(source_line)
|
684
|
-
source_line = source_line.gsub(/(^'|'$)/, '"') if source_line.start_with?("'") && source_line.end_with?("'")
|
685
|
-
source_line = source_line.gsub(/(^\(|\)$)/, '') if source_line.start_with?("(") && source_line.end_with?(")")
|
686
|
-
source_line
|
687
|
-
end
|
688
|
-
|
689
|
-
# Extracts pd source line expression.
|
690
|
-
#
|
691
|
-
# Example:
|
692
|
-
#
|
693
|
-
# __extract_pd_expression__("pd (x=1)")
|
694
|
-
#
|
695
|
-
# outputs `(x=1)`
|
696
|
-
def __extract_pd_expression__(source_line)
|
697
|
-
source_line.to_s.strip
|
698
|
-
end
|