Module: Loba

Defined in:
lib/loba.rb,
lib/loba/error.rb,
lib/loba/value.rb,
lib/loba/version.rb,
lib/loba/internal.rb,
lib/loba/timestamp.rb,
lib/loba/internal/value.rb,
lib/loba/internal/platform.rb,
lib/loba/internal/settings.rb,
lib/loba/internal/time_keeper.rb,
lib/loba/internal/platform/formatter.rb,
lib/loba/internal/value/value_helper.rb,
lib/loba/internal/platform/within_rails.rb

Overview

rubocop:disable Style/Documentation

Defined Under Namespace

Modules: Internal Classes: Error, InvalidLogdevOptionError, InvalidLoggerOptionError, InvalidOutOptionError

Constant Summary collapse

VERSION =

Semantic version number

'2.1.0'.freeze

Class Method Summary collapse

Class Method Details

.timestamp(production: false, log: false, logger: nil, logdev: nil, out: true) ⇒ NilClass

Note:

To avoid doubled output, if a non-Rails logger is to be logged to and logdev is set to $stdout, then output will be suppressed (i.e., settings.out is false). Doubled output can still occur; in that case, explicitly use out: false.

Outputs a timestamped notice, useful for quick traces to see the code path. Also does a simple elapsed time check since the previous timestamp notice to help with quick, minimalist profiling.

Examples:

Basic use

def hello
  Loba.timestamp
end
#=> [TIMESTAMP] #=0001, diff=0.000463, at=1451615389.505411, in=/path/to/file.rb:2:in 'hello'

Forced to output when in production environment

def hello
  Loba.ts production: true # Loba.ts is a shorthand alias for Loba.timestamp
end
#=> [TIMESTAMP] #=0001, diff=0.000463, at=1451615389.505411, in=/path/to/file.rb:2:in 'hello'

Forced to output to log in addition to $stdout

def hello
  Loba.timestamp log: true
end
#=> [TIMESTAMP] #=0001, diff=0.000463, at=1451615389.505411, in=/path/to/file.rb:2:in 'hello'

Parameters:

  • production (boolean) (defaults to: false)

    set to true if this timestamp notice is to be recorded when running in a Rails production environment

  • log (boolean) (defaults to: false)

    set to false if no logging is ever wanted (default when not in Rails and logger is nil); set to true if logging is always wanted (default when in Rails or when logger is set or out is false);

  • logger (Logger) (defaults to: nil)

    override logging with specified Ruby Logger

  • logdev (nil, String, IO, File::NULL) (defaults to: nil)

    custom log device to use (when not in Rails); ignored if logger is set; must be filename or IO object

  • out (boolean) (defaults to: true)

    set to false if console output is to be suppressed

Returns:

  • (NilClass)

    nil



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/loba/timestamp.rb', line 38

def timestamp( # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  production: false,
  log: false,
  logger: nil,
  logdev: nil,
  out: true
)
  settings = Internal::Settings.new(
    log: log, logger: logger, logdev: logdev, out: out, production: production
  )

  return unless settings.enabled?

  # NOTE: while tempting, memoizing loba_logger can lead to surprises if
  #   Rails presence isn't constant
  writer = Internal::Platform.writer(settings: settings)

  begin
    stats = Internal::TimeKeeper.instance.ping
    writer.call(
      # 60: light_black / grey
      "#{Rainbow('[TIMESTAMP]').black.bg(60)}" \
      "#{Rainbow(' #=').yellow.bg(:default)}" \
      "#{format('%04d', stats[:number])}" \
      "#{Rainbow(', diff=').yellow}" \
      "#{format('%.6f', stats[:change])}" \
      "#{Rainbow(', at=').yellow}" \
      "#{format('%.6f', stats[:now].round(6).to_f)}" \
      "#{Rainbow("    \t(in #{caller(1..1).first})").color(60)}" # warning: nested interpolation
    )
  rescue StandardError => e
    writer.call Rainbow("[TIMESTAMP] #=FAIL, in=#{caller(1..1).first}, err=#{e}").red
  end

  nil
end

.ts(production: false, log: false, logger: nil, logdev: nil, out: true) ⇒ NilClass

Note:

To avoid doubled output, if a non-Rails logger is to be logged to and logdev is set to $stdout, then output will be suppressed (i.e., settings.out is false). Doubled output can still occur; in that case, explicitly use out: false.

Outputs a timestamped notice, useful for quick traces to see the code path. Also does a simple elapsed time check since the previous timestamp notice to help with quick, minimalist profiling. Shorthand alias for Loba.timestamp.

Examples:

Basic use

def hello
  Loba.timestamp
end
#=> [TIMESTAMP] #=0001, diff=0.000463, at=1451615389.505411, in=/path/to/file.rb:2:in 'hello'

Forced to output when in production environment

def hello
  Loba.ts production: true # Loba.ts is a shorthand alias for Loba.timestamp
end
#=> [TIMESTAMP] #=0001, diff=0.000463, at=1451615389.505411, in=/path/to/file.rb:2:in 'hello'

Forced to output to log in addition to $stdout

def hello
  Loba.timestamp log: true
end
#=> [TIMESTAMP] #=0001, diff=0.000463, at=1451615389.505411, in=/path/to/file.rb:2:in 'hello'

Parameters:

  • production (boolean) (defaults to: false)

    set to true if this timestamp notice is to be recorded when running in a Rails production environment

  • log (boolean) (defaults to: false)

    set to false if no logging is ever wanted (default when not in Rails and logger is nil); set to true if logging is always wanted (default when in Rails or when logger is set or out is false);

  • logger (Logger) (defaults to: nil)

    override logging with specified Ruby Logger

  • logdev (nil, String, IO, File::NULL) (defaults to: nil)

    custom log device to use (when not in Rails); ignored if logger is set; must be filename or IO object

  • out (boolean) (defaults to: true)

    set to false if console output is to be suppressed

Returns:

  • (NilClass)

    nil



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/loba/timestamp.rb', line 78

def timestamp( # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  production: false,
  log: false,
  logger: nil,
  logdev: nil,
  out: true
)
  settings = Internal::Settings.new(
    log: log, logger: logger, logdev: logdev, out: out, production: production
  )

  return unless settings.enabled?

  # NOTE: while tempting, memoizing loba_logger can lead to surprises if
  #   Rails presence isn't constant
  writer = Internal::Platform.writer(settings: settings)

  begin
    stats = Internal::TimeKeeper.instance.ping
    writer.call(
      # 60: light_black / grey
      "#{Rainbow('[TIMESTAMP]').black.bg(60)}" \
      "#{Rainbow(' #=').yellow.bg(:default)}" \
      "#{format('%04d', stats[:number])}" \
      "#{Rainbow(', diff=').yellow}" \
      "#{format('%.6f', stats[:change])}" \
      "#{Rainbow(', at=').yellow}" \
      "#{format('%.6f', stats[:now].round(6).to_f)}" \
      "#{Rainbow("    \t(in #{caller(1..1).first})").color(60)}" # warning: nested interpolation
    )
  rescue StandardError => e
    writer.call Rainbow("[TIMESTAMP] #=FAIL, in=#{caller(1..1).first}, err=#{e}").red
  end

  nil
end

.val(argument, label: nil, inspect: true, production: false, log: false, logger: nil, logdev: nil, out: true) ⇒ NilClass

Note:

To avoid doubled output, if a non-Rails logger is to be logged to and logdev is set to $stdout, then output will be suppressed (i.e., settings.out is false). Doubled output can still occur; in that case, explicitly use out: false.

Outputs a value notice showing value of provided argument including method and class identification. rubocop:disable Layout/LineLength Shorthand alias for Loba.value.

Examples:

Using Symbol as argument

class HelloWorld
  def hello(name)
Loba.value :name # putting Loba statement to far left helps remember to remove later
    puts "Hello, #{name}!"
  end
end
HelloWorld.new.hello("Charlie")
#=> [HelloWorld#hello] name: Charlie        (at /path/to/file/hello_world.rb:3:in 'hello')
#=> Hello, Charlie!

Using non-Symbol as argument

class HelloWorld
  def hello(name)
Loba.val name # Loba.val is a shorthand alias for Loba.value
    puts "Hello, #{name}!"
  end
end
HelloWorld.new.hello("Charlie")
#=> [HelloWorld#hello] Charlie        (at /path/to/file/hello_world.rb:3:in 'hello')
#=> Hello, Charlie!

Using non-Symbol as argument with a label

class HelloWorld
  def hello(name)
Loba.value name, "Name:"
    puts "Hello, #{name}!"
  end
end
HelloWorld.new.hello("Charlie")
#=> [HelloWorld#hello] Name: Charlie        (at /path/to/file/hello_world.rb:3:in 'hello')
#=> Hello, Charlie!

Parameters:

  • argument (various)

    (required) the value to be evaluated and shown; if given as a Symbol, a label based on the argument will proceed the value the argument refers to

  • label (String) (defaults to: nil)

    explicit label to be used instead of attempting to infer from the argument; default is to attempt to infer a label from the argument

  • inspect (boolean) (defaults to: true)

    true if this value notice is to use #inspect against the content being evaluated; otherwise, false

  • production (boolean) (defaults to: false)

    set to true if the value notice is to be recorded when running in a Rails production environment

  • log (boolean) (defaults to: false)

    set to false if no logging is ever wanted (default when not in Rails and logger is nil); set to true if logging is always wanted (default when in Rails or when logger is set or out is false);

  • logger (Logger) (defaults to: nil)

    override logging with specified Ruby Logger

  • logdev (nil, String, IO, File::NULL) (defaults to: nil)

    custom log device to use (when not in Rails); ignored if logger is set; must be filename or IO object

  • out (boolean) (defaults to: true)

    set to false if console output is to be suppressed

Returns:

  • (NilClass)

    nil



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/loba/value.rb', line 101

def value( # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/ParameterLists
  argument,
  label: nil,
  inspect: true,
  production: false,
  log: false,
  logger: nil,
  logdev: nil,
  out: true
)
  settings = Internal::Settings.new(
    log: log, logger: logger, logdev: logdev, out: out, production: production
  )

  return unless settings.enabled?

  text = Internal::Value.phrases(
    argument: (argument.nil? ? :nil : argument),
    label: label,
    inspect: inspect,
    depth_offset: 1
  )

  Internal::Platform.writer(settings: settings).call(
    # NOTE: while tempting, memoizing Internal::Platform.logger can lead to surprises
    #   if Rails presence isn't constant
    #
    # warning: nested interpolation below (slight help to performance)
    # 60: light_black
    # 62: light_green
    "#{Rainbow("#{text[:tag]} ").green.bg(:default)}" \
    "#{Rainbow("#{text[:label]} ").color(62)}" \
    "#{text[:value]}" \
    "#{Rainbow("    \t(in #{text[:line]})").color(60)}"
  )

  nil
end

.value(argument, label: nil, inspect: true, production: false, log: false, logger: nil, logdev: nil, out: true) ⇒ NilClass

Note:

To avoid doubled output, if a non-Rails logger is to be logged to and logdev is set to $stdout, then output will be suppressed (i.e., settings.out is false). Doubled output can still occur; in that case, explicitly use out: false.

Outputs a value notice showing value of provided argument including method and class identification.

Examples:

Using Symbol as argument

class HelloWorld
  def hello(name)
Loba.value :name # putting Loba statement to far left helps remember to remove later
    puts "Hello, #{name}!"
  end
end
HelloWorld.new.hello("Charlie")
#=> [HelloWorld#hello] name: Charlie        (at /path/to/file/hello_world.rb:3:in 'hello')
#=> Hello, Charlie!

Using non-Symbol as argument

class HelloWorld
  def hello(name)
Loba.val name # Loba.val is a shorthand alias for Loba.value
    puts "Hello, #{name}!"
  end
end
HelloWorld.new.hello("Charlie")
#=> [HelloWorld#hello] Charlie        (at /path/to/file/hello_world.rb:3:in 'hello')
#=> Hello, Charlie!

Using non-Symbol as argument with a label

class HelloWorld
  def hello(name)
Loba.value name, "Name:"
    puts "Hello, #{name}!"
  end
end
HelloWorld.new.hello("Charlie")
#=> [HelloWorld#hello] Name: Charlie        (at /path/to/file/hello_world.rb:3:in 'hello')
#=> Hello, Charlie!

Parameters:

  • argument (various)

    (required) the value to be evaluated and shown; if given as a Symbol, a label based on the argument will proceed the value the argument refers to

  • label (String) (defaults to: nil)

    explicit label to be used instead of attempting to infer from the argument; default is to attempt to infer a label from the argument

  • inspect (boolean) (defaults to: true)

    true if this value notice is to use #inspect against the content being evaluated; otherwise, false

  • production (boolean) (defaults to: false)

    set to true if the value notice is to be recorded when running in a Rails production environment

  • log (boolean) (defaults to: false)

    set to false if no logging is ever wanted (default when not in Rails and logger is nil); set to true if logging is always wanted (default when in Rails or when logger is set or out is false);

  • logger (Logger) (defaults to: nil)

    override logging with specified Ruby Logger

  • logdev (nil, String, IO, File::NULL) (defaults to: nil)

    custom log device to use (when not in Rails); ignored if logger is set; must be filename or IO object

  • out (boolean) (defaults to: true)

    set to false if console output is to be suppressed

Returns:

  • (NilClass)

    nil



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/loba/value.rb', line 58

def value( # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/ParameterLists
  argument,
  label: nil,
  inspect: true,
  production: false,
  log: false,
  logger: nil,
  logdev: nil,
  out: true
)
  settings = Internal::Settings.new(
    log: log, logger: logger, logdev: logdev, out: out, production: production
  )

  return unless settings.enabled?

  text = Internal::Value.phrases(
    argument: (argument.nil? ? :nil : argument),
    label: label,
    inspect: inspect,
    depth_offset: 1
  )

  Internal::Platform.writer(settings: settings).call(
    # NOTE: while tempting, memoizing Internal::Platform.logger can lead to surprises
    #   if Rails presence isn't constant
    #
    # warning: nested interpolation below (slight help to performance)
    # 60: light_black
    # 62: light_green
    "#{Rainbow("#{text[:tag]} ").green.bg(:default)}" \
    "#{Rainbow("#{text[:label]} ").color(62)}" \
    "#{text[:value]}" \
    "#{Rainbow("    \t(in #{text[:line]})").color(60)}"
  )

  nil
end