Module: PutsDebuggerer
- Defined in:
- lib/puts_debuggerer.rb,
lib/puts_debuggerer/source_file.rb,
lib/puts_debuggerer/run_determiner.rb
Defined Under Namespace
Modules: RunDeterminer Classes: SourceFile
Constant Summary collapse
- SOURCE_LINE_COUNT_DEFAULT =
1- HEADER_DEFAULT =
'>'*80
- WRAPPER_DEFAULT =
'*'*80
- FOOTER_DEFAULT =
'<'*80
- LOGGER_FORMATTER_DECORATOR =
proc { |original_formatter| proc { |severity, datetime, progname, msg| original_formatter.call(severity, datetime, progname, msg.pd_inspect) } }
- LOGGING_LAYOUT_DECORATOR =
proc {|original_layout| original_layout.clone.tap do |layout| layout.singleton_class.class_eval do alias original_format_obj format_obj def format_obj(obj) obj.pdi # alias to pd_inspect end end end }
- RETURN_DEFAULT =
true- OBJECT_PRINTER_DEFAULT =
lambda do |object, =nil, source_line_count=nil, run_number=nil| lambda do if object.is_a?(Exception) if RUBY_ENGINE == 'opal' object.backtrace.each { |line| puts line } else puts object. end elsif PutsDebuggerer.print_engine.is_a?(Proc) PutsDebuggerer.print_engine.call(object) else send(PutsDebuggerer.print_engine, object) end end end
- PRINTER_DEFAULT =
:puts- PRINTER_RAILS =
lambda do |output| puts output if Rails.env.test? Rails.logger.debug(output) end
- PRINT_ENGINE_DEFAULT =
:ap- PRINTER_MESSAGE_INVALID =
'printer must be a valid global method symbol (e.g. :puts), a logger, or a lambda/proc receiving a text arg'- 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'- ANNOUNCER_DEFAULT =
'[PD]'- FORMATTER_DEFAULT =
-> (data) { puts data[:wrapper] if data[:wrapper] puts data[:header] if data[:header] print "#{data[:announcer]} #{data[:file]}#{':' if data[:line_number]}#{data[:line_number]} in #{[data[:class], data[:method]].compact.join('.')}#{" (run:#{data[:run_number]})" if data[:run_number]}#{__format_pd_expression__(data[:pd_expression], data[:object])} " data[:object_printer].call puts data[:caller].map {|l| ' ' + l} unless data[:caller].to_a.empty? puts data[:footer] if data[:footer] puts data[:wrapper] if data[:wrapper] }
- CALLER_DEPTH_ZERO =
depth includes pd + with_options method + nested block + build_pd_data method
4- CALLER_DEPTH_ZERO_OPAL =
depth includes pd + with_options method + nested block + build_pd_data method
-1 #depth includes pd + with_options method + nested block + build_pd_data method
- STACK_TRACE_CALL_LINE_NUMBER_REGEX =
/\:(\d+)\:in /- STACK_TRACE_CALL_SOURCE_FILE_REGEX =
/[ ]*([^:]+)\:\d+\:in /- STACK_TRACE_CALL_SOURCE_FILE_REGEX_OPAL =
/(http[^\)]+)/- STACK_TRACE_CALL_METHOD_REGEX =
/`([^']+)'$/- OPTIONS =
[:app_path, :source_line_count, :header, :h, :wrapper, :w, :footer, :f, :printer, :print_engine, :announcer, :formatter, :caller, :run_at]
- OPTION_ALIASES =
{ a: :announcer, c: :caller, h: :header, f: :footer, w: :wrapper, }
Class Attribute Summary collapse
-
.announcer ⇒ Object
Announcer (e.g. [PD]) to announce every print out with (default: “[PD]”).
-
.app_path ⇒ Object
Application root path to exclude when printing out file path.
-
.caller ⇒ Object
Caller backtrace included at the end of every print out Passed an argument of true/false, nil, or depth as an integer.
-
.footer ⇒ Object
readonly
Footer to include at the bottom of every print out.
-
.formatter ⇒ Object
Formatter used in every print out Passed a data argument with the following keys: * :announcer (string) * :caller (array) * :file (string) * :wrapper (string) * :footer (string) * :header (string) * :line_number (string) * :pd_expression (string) * :object (object) * :object_printer (proc) * :source_line_count (integer).
-
.header ⇒ Object
readonly
Header to include at the top of every print out.
-
.logger_original_formatter ⇒ Object
readonly
Logger original formatter before it was decorated with PutsDebuggerer::LOGGER_FORMATTER_DECORATOR upon setting the logger as a printer.
-
.logging_original_layouts ⇒ Object
readonly
Logging library original layouts before being decorated with PutsDebuggerer::LOGGING_LAYOUT_DECORATOR upon setting the Logging library logger as a printer.
-
.printer ⇒ Object
Printer is a global method symbol, lambda expression, or logger to use in printing to the user.
-
.run_at ⇒ Object
When to run as specified by an index, array, or range.
-
.source_line_count ⇒ Object
Source Line Count.
-
.wrapper ⇒ Object
readonly
Wrapper to include at the top and bottom of every print out (both header and footer).
Class Method Summary collapse
- .caller? ⇒ Boolean
- .convert_options(hash) ⇒ Object
- .determine_object(objects) ⇒ Object
- .determine_options(objects) ⇒ Object
- .determine_printer(options) ⇒ Object
- .determine_run_at(options) ⇒ Object
-
.options ⇒ Object
Options as a hash.
-
.options=(hash) ⇒ Object
Sets options included in hash.
-
.print_engine ⇒ Object
Print engine is similar to
printer, except it is focused on the scope of formatting the data object being printed (excluding metadata such as file name, line number, and expression, which are handled by theprinter). - .print_engine=(engine) ⇒ Object
- .print_engine_default ⇒ Object
- .printer_default ⇒ Object
- .run_at? ⇒ Boolean
Class Attribute Details
.announcer ⇒ Object
Announcer (e.g. [PD]) to announce every print out with (default: “[PD]”)
Example:
PutsDebuggerer.announcer = "*** PD ***\n "
pd (x=1)
Prints out:
*** PD ***
/Users/User/example.rb:2
> pd x=1
=> 1
305 306 307 |
# File 'lib/puts_debuggerer.rb', line 305 def announcer @announcer end |
.app_path ⇒ Object
Application root path to exclude when printing out file path
Example:
# File Name: /Users/User/sample_app/lib/sample.rb
PutsDebuggerer.app_path = '/Users/User/sample_app'
pd (x=1)
Prints out:
[PD] lib/sample.rb:3
> pd x=1
=> "1"
92 93 94 |
# File 'lib/puts_debuggerer.rb', line 92 def app_path @app_path end |
.caller ⇒ Object
Caller backtrace included at the end of every print out Passed an argument of true/false, nil, or depth as an integer.
-
true and -1 means include full caller backtrace
-
false and nil means do not include caller backtrace
-
depth (0-based) means include limited caller backtrace depth
Example:
# File Name: /Users/User/sample_app/lib/sample.rb
PutsDebuggerer.caller = 3
pd (x=1)
Prints out:
[PD] /Users/User/sample_app/lib/sample.rb:3
> pd x=1
=> "1"
/Users/User/sample_app/lib/master_samples.rb:368:in `block (3 levels) in <top (required)>'
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in `eval'
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/workspace.rb:87:in `evaluate'
/Users/User/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/irb/context.rb:381:in `evaluate'
382 383 384 |
# File 'lib/puts_debuggerer.rb', line 382 def caller @caller end |
.footer ⇒ Object (readonly)
Footer to include at the bottom of every print out.
-
Default value is
nil -
Value
trueenables footer as ‘’*‘*80` -
Value
false,nil, or empty string disables footer -
Any other string value gets set as a custom footer
Example:
PutsDebuggerer. = true
pd (x=1)
Prints out:
[PD] /Users/User/example.rb:2
> pd x=1
=> "1"
********************************************************************************
175 176 177 |
# File 'lib/puts_debuggerer.rb', line 175 def end |
.formatter ⇒ Object
Formatter used in every print out Passed a data argument with the following keys:
-
:announcer (string)
-
:caller (array)
-
:file (string)
-
:wrapper (string)
-
:footer (string)
-
:header (string)
-
:line_number (string)
-
:pd_expression (string)
-
:object (object)
-
:object_printer (proc)
-
:source_line_count (integer)
NOTE: data for :object_printer is not a string, yet a proc that must be called to output value. It is a proc as it automatically handles usage of print_engine and encapsulates its details. In any case, data for :object is available should one want to avoid altogether.
Example:
PutsDebuggerer.formatter = -> (data) {
puts "-<#{data[:announcer]}>-"
puts "HEADER: #{data[:header]}"
puts "FILE: #{data[:file]}"
puts "LINE: #{data[:line_number]}"
puts "EXPRESSION: #{data[:pd_expression]}"
print "PRINT OUT: "
data[:object_printer].call
puts "CALLER: #{data[:caller].to_a.first}"
puts "FOOTER: #{data[:footer]}"
}
pd (x=1)
Prints out:
-<[PD]>-
FILE: /Users/User/example.rb
HEADER: ********************************************************************************
LINE: 9
EXPRESSION: x=1
PRINT OUT: 1
CALLER: #/Users/User/master_examples.rb:83:in `block (3 levels) in <top (required)>'
FOOTER: ********************************************************************************
355 356 357 |
# File 'lib/puts_debuggerer.rb', line 355 def formatter @formatter end |
.header ⇒ Object (readonly)
Header to include at the top of every print out.
-
Default value is
nil -
Value
trueenables header as ‘’*‘*80` -
Value
false,nil, or empty string disables header -
Any other string value gets set as a custom header
Example:
PutsDebuggerer.header = true
pd (x=1)
Prints out:
********************************************************************************
[PD] /Users/User/example.rb:2
> pd x=1
=> "1"
137 138 139 |
# File 'lib/puts_debuggerer.rb', line 137 def header @header end |
.logger_original_formatter ⇒ Object (readonly)
Logger original formatter before it was decorated with PutsDebuggerer::LOGGER_FORMATTER_DECORATOR upon setting the logger as a printer.
243 244 245 |
# File 'lib/puts_debuggerer.rb', line 243 def logger_original_formatter @logger_original_formatter end |
.logging_original_layouts ⇒ Object (readonly)
Logging library original layouts before being decorated with PutsDebuggerer::LOGGING_LAYOUT_DECORATOR upon setting the Logging library logger as a printer.
247 248 249 |
# File 'lib/puts_debuggerer.rb', line 247 def logging_original_layouts @logging_original_layouts end |
.printer ⇒ Object
Printer is a global method symbol, lambda expression, or logger to use in printing to the user. Examples of a global method are :puts and :print. An example of a lambda expression is ‘lambda {|output| Rails.logger.ap(output)}` Examples of a logger are a Ruby Logger instance or Logging::Logger instance
Defaults to :puts In Rails, it defaults to: ‘lambda {|output| Rails.logger.ap(output)}`
Example:
# File Name: /Users/User/example.rb PutsDebuggerer.printer = lambda {|output| Rails.logger.error(output)} str = “Hello” pd str
Prints out in the Rails app log as error lines:
- PD
-
/Users/User/example.rb:5
> pd str
=> Hello
213 214 215 |
# File 'lib/puts_debuggerer.rb', line 213 def printer @printer end |
.run_at ⇒ Object
When to run as specified by an index, array, or range.
-
Default value is
nilmeaning always -
Value as an Integer index (1-based) specifies at which run to print once
-
Value as an Array of indices specifies at which runs to print multiple times
-
Value as a range specifies at which runs to print multiple times, indefinitely if it ends with ..-1
Example:
PutsDebuggerer.run_at = 1
pd (x=1) # prints standard PD output
pd (x=1) # prints nothing
PutsDebuggerer.run_at = 2
pd (x=1) # prints nothing
pd (x=1) # prints standard PD output
PutsDebuggerer.run_at = [1, 3]
pd (x=1) # prints standard PD output
pd (x=1) # prints nothing
pd (x=1) # prints standard PD output
pd (x=1) # prints nothing
PutsDebuggerer.run_at = 3..5
pd (x=1) # prints nothing
pd (x=1) # prints nothing
pd (x=1) # prints standard PD output
pd (x=1) # prints standard PD output
pd (x=1) # prints standard PD output
pd (x=1) # prints nothing
pd (x=1) # prints nothing
PutsDebuggerer.run_at = 3...6
pd (x=1) # prints nothing
pd (x=1) # prints nothing
pd (x=1) # prints standard PD output
pd (x=1) # prints standard PD output
pd (x=1) # prints standard PD output
pd (x=1) # prints nothing
PutsDebuggerer.run_at = 3..-1
pd (x=1) # prints nothing
pd (x=1) # prints nothing
pd (x=1) # prints standard PD output
pd (x=1) ... continue printing indefinitely on all subsequent runs
PutsDebuggerer.run_at = 3...-1
pd (x=1) # prints nothing
pd (x=1) # prints nothing
pd (x=1) # prints standard PD output
pd (x=1) ... continue printing indefinitely on all subsequent runs
472 473 474 |
# File 'lib/puts_debuggerer.rb', line 472 def run_at @run_at end |
.source_line_count ⇒ Object
Source Line Count.
-
Default value is
1
Example:
PutsDebuggerer.source_line_count = 2
pd (true ||
false), source_line_count: 2
Prints out:
********************************************************************************
[PD] /Users/User/example.rb:2
> pd (true ||
false), source_line_count: 2
=> "true"
114 115 116 |
# File 'lib/puts_debuggerer.rb', line 114 def source_line_count @source_line_count end |
.wrapper ⇒ Object (readonly)
Wrapper to include at the top and bottom of every print out (both header and footer).
-
Default value is
nil -
Value
trueenables wrapper as ‘’*‘*80` -
Value
false,nil, or empty string disables wrapper -
Any other string value gets set as a custom wrapper
Example:
PutsDebuggerer.wrapper = true
pd (x=1)
Prints out:
[PD] /Users/User/example.rb:2
> pd x=1
=> "1"
********************************************************************************
156 157 158 |
# File 'lib/puts_debuggerer.rb', line 156 def wrapper @wrapper end |
Class Method Details
.caller? ⇒ Boolean
392 393 394 |
# File 'lib/puts_debuggerer.rb', line 392 def caller? !!caller end |
.convert_options(hash) ⇒ Object
491 492 493 |
# File 'lib/puts_debuggerer.rb', line 491 def (hash) Hash[hash.map { |key, value| OPTION_ALIASES[key] ? ( value == :t ? [OPTION_ALIASES[key], true] : [OPTION_ALIASES[key], value] ) : [key, value]}] end |
.determine_object(objects) ⇒ Object
495 496 497 |
# File 'lib/puts_debuggerer.rb', line 495 def determine_object(objects) objects.compact.size > 1 ? objects : objects.first end |
.determine_options(objects) ⇒ Object
482 483 484 485 486 487 488 489 |
# File 'lib/puts_debuggerer.rb', line 482 def (objects) if objects.size > 1 && objects.last.is_a?(Hash) (objects.delete_at(-1)) elsif objects.size == 1 && objects.first.is_a?(Hash) hash = objects.first (hash.slice(*OPTIONS)) end end |
.determine_printer(options) ⇒ Object
503 504 505 506 507 508 509 |
# File 'lib/puts_debuggerer.rb', line 503 def determine_printer() if && .has_key?(:printer) [:printer] else PutsDebuggerer.printer end end |
.determine_run_at(options) ⇒ Object
499 500 501 |
# File 'lib/puts_debuggerer.rb', line 499 def determine_run_at() (( && [:run_at]) || PutsDebuggerer.run_at) end |
.options ⇒ Object
Options as a hash. Useful for reading and backing up options
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/puts_debuggerer.rb', line 398 def { header: header, wrapper: wrapper, footer: , printer: printer, print_engine: print_engine, source_line_count: source_line_count, app_path: app_path, announcer: announcer, formatter: formatter, caller: caller, run_at: run_at } end |
.options=(hash) ⇒ Object
Sets options included in hash
415 416 417 418 419 |
# File 'lib/puts_debuggerer.rb', line 415 def (hash) hash.each do |option, value| send("#{option}=", value) end end |
.print_engine ⇒ Object
Print engine is similar to printer, except it is focused on the scope of formatting the data object being printed (excluding metadata such as file name, line number, and expression, which are handled by the printer). As such, it is also a global method symbol or lambda expression. Examples of global methods are :p, :ap, and :pp. An example of a lambda expression is ‘lambda {|object| puts object.to_a.join(“ | ”)}`
Defaults to [awesome_print](github.com/awesome-print/awesome_print).
Example:
# File Name: /Users/User/example.rb
require 'awesome_print'
PutsDebuggerer.print_engine = :p
array = [1, [2, 3]]
pd array
Prints out:
[PD] /Users/User/example.rb:5
> pd array
=> [1, [2, 3]]
]
272 273 274 275 276 277 278 |
# File 'lib/puts_debuggerer.rb', line 272 def print_engine if @print_engine.nil? require 'awesome_print' if RUBY_ENGINE != 'opal' @print_engine = print_engine_default end @print_engine end |
.print_engine=(engine) ⇒ Object
280 281 282 283 284 285 286 |
# File 'lib/puts_debuggerer.rb', line 280 def print_engine=(engine) if engine.is_a?(Proc) || engine.nil? @print_engine = engine else @print_engine = method(engine).name rescue raise(PRINT_ENGINE_MESSAGE_INVALID) end end |
.print_engine_default ⇒ Object
288 289 290 |
# File 'lib/puts_debuggerer.rb', line 288 def print_engine_default Object.const_defined?(:AwesomePrint) ? PRINT_ENGINE_DEFAULT : :p end |
.printer_default ⇒ Object
237 238 239 |
# File 'lib/puts_debuggerer.rb', line 237 def printer_default Object.const_defined?(:Rails) ? PRINTER_RAILS : PRINTER_DEFAULT end |
.run_at? ⇒ Boolean
478 479 480 |
# File 'lib/puts_debuggerer.rb', line 478 def run_at? !!@run_at end |