puts_debuggerer 0.7.1 → 0.10.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 +5 -5
- data/CHANGELOG.md +73 -0
- data/LICENSE.txt +1 -1
- data/README.md +548 -63
- data/VERSION +1 -0
- data/lib/pd.rb +1 -0
- data/lib/puts_debuggerer.rb +272 -146
- 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 +68 -26
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.10.0
|
data/lib/pd.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'puts_debuggerer'
|
data/lib/puts_debuggerer.rb
CHANGED
@@ -1,21 +1,70 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'stringio'
|
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
|
3
16
|
|
4
17
|
module PutsDebuggerer
|
18
|
+
SOURCE_LINE_COUNT_DEFAULT = 1
|
5
19
|
HEADER_DEFAULT = '*'*80
|
20
|
+
WRAPPER_DEFAULT = '*'*80
|
6
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
|
49
|
+
PRINTER_DEFAULT = :puts
|
50
|
+
PRINTER_RAILS = lambda do |output|
|
51
|
+
puts output if Rails.env.test?
|
52
|
+
Rails.logger.debug(output)
|
53
|
+
end
|
7
54
|
PRINT_ENGINE_DEFAULT = :ap
|
8
|
-
|
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'
|
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'
|
9
57
|
ANNOUNCER_DEFAULT = '[PD]'
|
10
58
|
FORMATTER_DEFAULT = -> (data) {
|
59
|
+
puts data[:wrapper] if data[:wrapper]
|
11
60
|
puts data[:header] if data[:header]
|
12
|
-
print "#{data[:announcer]} #{data[:file]}:#{data[:line_number]}#{__format_pd_expression__(data[:pd_expression], data[:object])} "
|
61
|
+
print "#{data[:announcer]} #{data[:file]}:#{data[:line_number]}#{" (run:#{data[:run_number]})" if data[:run_number]}#{__format_pd_expression__(data[:pd_expression], data[:object])} "
|
13
62
|
data[:object_printer].call
|
14
63
|
puts data[:caller].map {|l| ' ' + l} unless data[:caller].to_a.empty?
|
15
64
|
puts data[:footer] if data[:footer]
|
65
|
+
puts data[:wrapper] if data[:wrapper]
|
16
66
|
}
|
17
67
|
CALLER_DEPTH_ZERO = 4 #depth includes pd + with_options method + nested block + build_pd_data method
|
18
|
-
OBJECT_RUN_AT = {}
|
19
68
|
STACK_TRACE_CALL_LINE_NUMBER_REGEX = /\:(\d+)\:in /
|
20
69
|
STACK_TRACE_CALL_SOURCE_FILE_REGEX = /[ ]*([^:]+)\:\d+\:in /
|
21
70
|
|
@@ -39,6 +88,28 @@ module PutsDebuggerer
|
|
39
88
|
@app_path = (path || Rails.root.to_s) rescue nil
|
40
89
|
end
|
41
90
|
|
91
|
+
# Source Line Count.
|
92
|
+
# * Default value is `1`
|
93
|
+
#
|
94
|
+
# Example:
|
95
|
+
#
|
96
|
+
# PutsDebuggerer.source_line_count = 2
|
97
|
+
# pd (true ||
|
98
|
+
# false), source_line_count: 2
|
99
|
+
#
|
100
|
+
# Prints out:
|
101
|
+
#
|
102
|
+
# ********************************************************************************
|
103
|
+
# [PD] /Users/User/example.rb:2
|
104
|
+
# > pd (true ||
|
105
|
+
# false), source_line_count: 2
|
106
|
+
# => "true"
|
107
|
+
attr_reader :source_line_count
|
108
|
+
|
109
|
+
def source_line_count=(value)
|
110
|
+
@source_line_count = value || SOURCE_LINE_COUNT_DEFAULT
|
111
|
+
end
|
112
|
+
|
42
113
|
# Header to include at the top of every print out.
|
43
114
|
# * Default value is `nil`
|
44
115
|
# * Value `true` enables header as `'*'*80`
|
@@ -58,19 +129,24 @@ module PutsDebuggerer
|
|
58
129
|
# => "1"
|
59
130
|
attr_reader :header
|
60
131
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
132
|
+
# Wrapper to include at the top and bottom of every print out (both header and footer).
|
133
|
+
# * Default value is `nil`
|
134
|
+
# * Value `true` enables wrapper as `'*'*80`
|
135
|
+
# * Value `false`, `nil`, or empty string disables wrapper
|
136
|
+
# * Any other string value gets set as a custom wrapper
|
137
|
+
#
|
138
|
+
# Example:
|
139
|
+
#
|
140
|
+
# PutsDebuggerer.wrapper = true
|
141
|
+
# pd (x=1)
|
142
|
+
#
|
143
|
+
# Prints out:
|
144
|
+
#
|
145
|
+
# [PD] /Users/User/example.rb:2
|
146
|
+
# > pd x=1
|
147
|
+
# => "1"
|
148
|
+
# ********************************************************************************
|
149
|
+
attr_reader :wrapper
|
74
150
|
|
75
151
|
# Footer to include at the bottom of every print out.
|
76
152
|
# * Default value is `nil`
|
@@ -90,25 +166,87 @@ module PutsDebuggerer
|
|
90
166
|
# => "1"
|
91
167
|
# ********************************************************************************
|
92
168
|
attr_reader :footer
|
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}")
|
183
|
+
end
|
184
|
+
end
|
93
185
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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`.
|
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
|
190
|
+
#
|
191
|
+
# Defaults to `:puts`
|
192
|
+
# In Rails, it defaults to: `lambda {|output| Rails.logger.ap(output)}`
|
193
|
+
#
|
194
|
+
# Example:
|
195
|
+
#
|
196
|
+
# # File Name: /Users/User/example.rb
|
197
|
+
# PutsDebuggerer.printer = lambda {|output| Rails.logger.error(output)}
|
198
|
+
# str = "Hello"
|
199
|
+
# pd str
|
200
|
+
#
|
201
|
+
# Prints out in the Rails app log as error lines:
|
202
|
+
#
|
203
|
+
# [PD] /Users/User/example.rb:5
|
204
|
+
# > pd str
|
205
|
+
# => Hello
|
206
|
+
attr_reader :printer
|
207
|
+
|
208
|
+
def printer=(printer)
|
209
|
+
if printer.nil?
|
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)
|
222
|
+
end
|
223
|
+
elsif printer == false || printer.is_a?(Proc) || printer.respond_to?(:log) # a logger
|
224
|
+
@printer = printer
|
99
225
|
else
|
100
|
-
@
|
226
|
+
@printer = method(printer).name rescue raise(PRINTER_MESSAGE_INVALID)
|
101
227
|
end
|
102
228
|
end
|
103
|
-
|
104
|
-
def
|
105
|
-
|
229
|
+
|
230
|
+
def printer_default
|
231
|
+
Object.const_defined?(:Rails) ? PRINTER_RAILS : PRINTER_DEFAULT
|
106
232
|
end
|
107
|
-
|
108
|
-
#
|
109
|
-
#
|
110
|
-
|
111
|
-
|
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
|
241
|
+
|
242
|
+
# Print engine is similar to `printer`, except it is focused on the scope of formatting
|
243
|
+
# the data object being printed (excluding metadata such as file name, line number,
|
244
|
+
# and expression, which are handled by the `printer`).
|
245
|
+
# As such, it is also a global method symbol or lambda expression.
|
246
|
+
# Examples of global methods are `:p`, `:ap`, and `:pp`.
|
247
|
+
# An example of a lambda expression is `lambda {|object| puts object.to_a.join(" | ")}`
|
248
|
+
#
|
249
|
+
# Defaults to [awesome_print](https://github.com/awesome-print/awesome_print).
|
112
250
|
#
|
113
251
|
# Example:
|
114
252
|
#
|
@@ -128,17 +266,17 @@ module PutsDebuggerer
|
|
128
266
|
|
129
267
|
def print_engine=(engine)
|
130
268
|
if engine.nil?
|
131
|
-
|
132
|
-
@print_engine = lambda {|object| Rails.logger.ap(object)}
|
133
|
-
else
|
134
|
-
@print_engine = PRINT_ENGINE_DEFAULT
|
135
|
-
end
|
269
|
+
@print_engine = print_engine_default
|
136
270
|
elsif engine.is_a?(Proc)
|
137
271
|
@print_engine = engine
|
138
272
|
else
|
139
273
|
@print_engine = method(engine).name rescue raise(PRINT_ENGINE_MESSAGE_INVALID)
|
140
274
|
end
|
141
275
|
end
|
276
|
+
|
277
|
+
def print_engine_default
|
278
|
+
Object.const_defined?(:AwesomePrint) ? PRINT_ENGINE_DEFAULT : :p
|
279
|
+
end
|
142
280
|
|
143
281
|
# Announcer (e.g. [PD]) to announce every print out with (default: "[PD]")
|
144
282
|
#
|
@@ -164,12 +302,14 @@ module PutsDebuggerer
|
|
164
302
|
# * :announcer (string)
|
165
303
|
# * :caller (array)
|
166
304
|
# * :file (string)
|
305
|
+
# * :wrapper (string)
|
167
306
|
# * :footer (string)
|
168
307
|
# * :header (string)
|
169
308
|
# * :line_number (string)
|
170
309
|
# * :pd_expression (string)
|
171
310
|
# * :object (object)
|
172
311
|
# * :object_printer (proc)
|
312
|
+
# * :source_line_count (integer)
|
173
313
|
#
|
174
314
|
# NOTE: data for :object_printer is not a string, yet a proc that must
|
175
315
|
# be called to output value. It is a proc as it automatically handles usage
|
@@ -247,8 +387,11 @@ module PutsDebuggerer
|
|
247
387
|
def options
|
248
388
|
{
|
249
389
|
header: header,
|
390
|
+
wrapper: wrapper,
|
250
391
|
footer: footer,
|
392
|
+
printer: printer,
|
251
393
|
print_engine: print_engine,
|
394
|
+
source_line_count: source_line_count,
|
252
395
|
app_path: app_path,
|
253
396
|
announcer: announcer,
|
254
397
|
formatter: formatter,
|
@@ -325,53 +468,37 @@ module PutsDebuggerer
|
|
325
468
|
!!@run_at
|
326
469
|
end
|
327
470
|
|
328
|
-
|
329
|
-
|
330
|
-
def run_at_global_number=(value)
|
331
|
-
@run_at_global_number = value
|
471
|
+
def determine_options(objects)
|
472
|
+
objects.delete_at(-1) if objects.size > 1 && objects.last.is_a?(Hash)
|
332
473
|
end
|
333
474
|
|
334
|
-
def
|
335
|
-
|
475
|
+
def determine_object(objects)
|
476
|
+
objects.compact.size > 1 ? objects : objects.first
|
336
477
|
end
|
337
478
|
|
338
|
-
def
|
339
|
-
|
479
|
+
def determine_run_at(options)
|
480
|
+
((options && options[:run_at]) || PutsDebuggerer.run_at)
|
340
481
|
end
|
341
482
|
|
342
|
-
def
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
end
|
349
|
-
|
350
|
-
def init_run_at_number(object, run_at)
|
351
|
-
PutsDebuggerer::OBJECT_RUN_AT[[object,run_at]] = 1
|
352
|
-
end
|
353
|
-
|
354
|
-
def increment_run_at_number(object, run_at)
|
355
|
-
PutsDebuggerer::OBJECT_RUN_AT[[object,run_at]] += 1
|
356
|
-
end
|
357
|
-
|
358
|
-
def reset_run_at_number(object, run_at)
|
359
|
-
PutsDebuggerer::OBJECT_RUN_AT.delete([object, run_at])
|
360
|
-
end
|
361
|
-
|
362
|
-
def reset_run_at_numbers
|
363
|
-
PutsDebuggerer::OBJECT_RUN_AT.clear
|
483
|
+
def determine_printer(options)
|
484
|
+
if options && options.has_key?(:printer)
|
485
|
+
options[:printer]
|
486
|
+
else
|
487
|
+
PutsDebuggerer.printer
|
488
|
+
end
|
364
489
|
end
|
365
|
-
|
366
490
|
end
|
367
491
|
end
|
368
492
|
|
369
|
-
|
370
|
-
PutsDebuggerer.
|
371
|
-
PutsDebuggerer.
|
493
|
+
# setting values to nil defaults them properly
|
494
|
+
PutsDebuggerer.printer = nil
|
495
|
+
PutsDebuggerer.print_engine = nil
|
496
|
+
PutsDebuggerer.announcer = nil
|
497
|
+
PutsDebuggerer.formatter = nil
|
372
498
|
PutsDebuggerer.app_path = nil
|
373
499
|
PutsDebuggerer.caller = nil
|
374
500
|
PutsDebuggerer.run_at = nil
|
501
|
+
PutsDebuggerer.source_line_count = nil
|
375
502
|
|
376
503
|
# Prints object with bonus info such as file name, line number and source
|
377
504
|
# expression. Optionally prints out header and footer.
|
@@ -402,48 +529,57 @@ PutsDebuggerer.run_at = nil
|
|
402
529
|
# > pd "Show me the source of the bug: #{bug}"
|
403
530
|
# => "Show me the source of the bug: beattle"
|
404
531
|
# [PD] /Users/User/finance_calculator_app/pd_test.rb:4 "What line number am I?"
|
405
|
-
def pd(
|
406
|
-
|
407
|
-
|
408
|
-
|
532
|
+
def pd(*objects)
|
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)
|
409
544
|
__with_pd_options__(options) do |print_engine_options|
|
410
|
-
|
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
|
547
|
+
stdout = $stdout
|
548
|
+
$stdout = sio = StringIO.new
|
411
549
|
PutsDebuggerer.formatter.call(formatter_pd_data)
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
PutsDebuggerer.
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
550
|
+
$stdout = stdout
|
551
|
+
string = sio.string
|
552
|
+
if PutsDebuggerer.printer.is_a?(Proc)
|
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)
|
435
578
|
end
|
436
|
-
run_number = PutsDebuggerer.run_at_global_number
|
437
|
-
end
|
438
|
-
if run_at.is_a?(Integer)
|
439
|
-
run_pd = true if run_at == run_number
|
440
|
-
elsif run_at.is_a?(Array)
|
441
|
-
run_pd = true if run_at.include?(run_number)
|
442
|
-
elsif run_at.is_a?(Range)
|
443
|
-
run_pd = true if run_at.cover?(run_number) || (run_at.end == -1 && run_number >= run_at.begin)
|
444
579
|
end
|
445
580
|
end
|
446
|
-
|
581
|
+
|
582
|
+
printer ? object : string
|
447
583
|
end
|
448
584
|
|
449
585
|
# Provides caller line number starting 1 level above caller of
|
@@ -457,7 +593,7 @@ end
|
|
457
593
|
#
|
458
594
|
# prints out `3`
|
459
595
|
def __caller_line_number__(caller_depth=0)
|
460
|
-
caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_LINE_NUMBER_REGEX, 1].to_i
|
596
|
+
caller[caller_depth] && caller[caller_depth][PutsDebuggerer::STACK_TRACE_CALL_LINE_NUMBER_REGEX, 1].to_i
|
461
597
|
end
|
462
598
|
|
463
599
|
# Provides caller file starting 1 level above caller of
|
@@ -470,7 +606,7 @@ end
|
|
470
606
|
#
|
471
607
|
# prints out `lib/example.rb`
|
472
608
|
def __caller_file__(caller_depth=0)
|
473
|
-
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]
|
474
610
|
end
|
475
611
|
|
476
612
|
|
@@ -482,23 +618,14 @@ end
|
|
482
618
|
# puts __caller_source_line__
|
483
619
|
#
|
484
620
|
# prints out `puts __caller_source_line__`
|
485
|
-
def __caller_source_line__(caller_depth=0, source_file=nil, source_line_number=nil)
|
621
|
+
def __caller_source_line__(caller_depth=0, source_line_count=nil, source_file=nil, source_line_number=nil)
|
486
622
|
source_line_number ||= __caller_line_number__(caller_depth+1)
|
487
623
|
source_file ||= __caller_file__(caller_depth+1)
|
488
|
-
source_line =
|
624
|
+
source_line = ''
|
489
625
|
if source_file == '(irb)'
|
490
|
-
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
|
491
627
|
else
|
492
|
-
|
493
|
-
source_line = ''
|
494
|
-
done = false
|
495
|
-
f.each_line do |line|
|
496
|
-
if !done && f.lineno == source_line_number
|
497
|
-
source_line << line
|
498
|
-
done = true if Ripper.sexp_raw(source_line) || source_line.include?('%>') #the last condition is for erb support (unofficial)
|
499
|
-
source_line_number+=1
|
500
|
-
end
|
501
|
-
end
|
628
|
+
source_line = PutsDebuggerer::SourceFile.new(source_file).source(source_line_count, source_line_number)
|
502
629
|
end
|
503
630
|
source_line
|
504
631
|
end
|
@@ -514,43 +641,42 @@ def __with_pd_options__(options=nil)
|
|
514
641
|
PutsDebuggerer.options = permanent_options
|
515
642
|
end
|
516
643
|
|
517
|
-
def __build_pd_data__(object, print_engine_options=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)
|
518
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
|
519
649
|
pd_data = {
|
520
650
|
announcer: PutsDebuggerer.announcer,
|
521
|
-
file: __caller_file__(depth)
|
651
|
+
file: __caller_file__(depth)&.sub(PutsDebuggerer.app_path.to_s, ''),
|
522
652
|
line_number: __caller_line_number__(depth),
|
523
|
-
pd_expression: __caller_pd_expression__(depth),
|
653
|
+
pd_expression: __caller_pd_expression__(depth, source_line_count),
|
654
|
+
run_number: run_number,
|
524
655
|
object: object,
|
525
|
-
object_printer:
|
526
|
-
if PutsDebuggerer.print_engine.is_a?(Proc)
|
527
|
-
PutsDebuggerer.print_engine.call(object)
|
528
|
-
else
|
529
|
-
if print_engine_options.to_h.empty?
|
530
|
-
send(PutsDebuggerer.print_engine, object)
|
531
|
-
else
|
532
|
-
send(PutsDebuggerer.print_engine, object, print_engine_options) rescue send(PutsDebuggerer.print_engine, object)
|
533
|
-
end
|
534
|
-
end
|
535
|
-
end
|
656
|
+
object_printer: PutsDebuggerer::OBJECT_PRINTER_DEFAULT.call(object, print_engine_options, source_line_count, run_number)
|
536
657
|
}
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
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}?")
|
541
661
|
end
|
542
|
-
pd_data[:header] = PutsDebuggerer.header if PutsDebuggerer.header?
|
543
|
-
pd_data[:footer] = PutsDebuggerer.footer if PutsDebuggerer.footer?
|
544
662
|
pd_data
|
545
663
|
end
|
546
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
|
+
|
547
673
|
def __format_pd_expression__(expression, object)
|
548
674
|
"\n > #{expression}\n =>"
|
549
675
|
end
|
550
676
|
|
551
|
-
def __caller_pd_expression__(depth=0)
|
677
|
+
def __caller_pd_expression__(depth=0, source_line_count=nil)
|
552
678
|
# Caller Source Line Depth 2 = 1 to pd method + 1 to caller
|
553
|
-
source_line = __caller_source_line__(depth+1)
|
679
|
+
source_line = __caller_source_line__(depth+1, source_line_count)
|
554
680
|
source_line = __extract_pd_expression__(source_line)
|
555
681
|
source_line = source_line.gsub(/(^'|'$)/, '"') if source_line.start_with?("'") && source_line.end_with?("'")
|
556
682
|
source_line = source_line.gsub(/(^\(|\)$)/, '') if source_line.start_with?("(") && source_line.end_with?(")")
|
@@ -565,5 +691,5 @@ end
|
|
565
691
|
#
|
566
692
|
# outputs `(x=1)`
|
567
693
|
def __extract_pd_expression__(source_line)
|
568
|
-
source_line.strip
|
694
|
+
source_line.to_s.strip
|
569
695
|
end
|