Module: InjectedLogger

Defined in:
lib/injectedlogger.rb,
lib/injectedlogger/errors.rb,
lib/injectedlogger/logger.rb,
lib/injectedlogger/version.rb,
lib/injectedlogger/delegator.rb

Defined Under Namespace

Modules: Delegator Classes: Logger

Constant Summary collapse

Error =
Class.new StandardError
InUse =
Class.new Error
DefaultInjectionBlockMissing =
Class.new Error
UnsupportedLevels =
Class.new Error do
  def initalize(levels)
    super("logger does not support required levels #{levels.join ', '}")
  end
end
VERSION =
'0.0.13'

Class Method Summary collapse

Class Method Details

.after_injection(on: nil, &blk) ⇒ Object



23
24
25
26
# File 'lib/injectedlogger/logger.rb', line 23

def self.after_injection(on: nil, &blk)
  on = blk.binding.eval 'self' if on.nil?
  logger[on].after_hook = blk
end

.inject(*args, on:, **options) ⇒ Object



15
16
17
# File 'lib/injectedlogger/logger.rb', line 15

def self.inject(*args, on:, **options)
  logger[on].inject(*args, **options)
end

.inject!(*args, on:, **options) ⇒ Object



19
20
21
# File 'lib/injectedlogger/logger.rb', line 19

def self.inject!(*args, on:, **options)
  logger[on].inject!(*args, **options)
end

.injected?(on:) ⇒ Boolean

Returns:

  • (Boolean)


11
12
13
# File 'lib/injectedlogger/logger.rb', line 11

def self.injected?(on:)
  logger[on].injected?
end

.logger_known(as:, refers_to:) ⇒ Object



28
29
30
# File 'lib/injectedlogger/logger.rb', line 28

def self.logger_known(as:, refers_to:)
  logger[as] = logger[refers_to]
end

.use(*required, on: nil, as: nil, method_name: :logger, &blk) ⇒ Object

inject a default logger in case no one has set one for you:

module MyLogger

InjectedLogger.use :info, :debug, :invented do
  require 'logger'
  # parameters are inject() params, none is required, but if
  # logger is not present, a default one will be used.
  { logger: Logger.new(STDERR), prefix: '[mylogger]', ... }
end

end

class WantsLogging

include MyLogger

def some_method_needing_logging
  logger.info 'some info'
end

def some_method_with_invented_level_logging
  logger.invented do
    'some invented logging'
  end
end

end

This will only run the block passed to inject IFF there was no logger set up to be used by InjectedLogger, and it will only happen the first time the logger method is called, so that it does not ‘require’ anything if it is not needed. :)



36
37
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
74
75
76
77
78
79
80
81
82
# File 'lib/injectedlogger.rb', line 36

def self.use(*required, on: nil, as: nil, method_name: :logger, &blk)
  if on.nil?
    raise InjectedLogger::DefaultInjectionBlockMissing if blk.nil?
    on = blk.binding.eval 'self'
  end
  on = on.singleton_class unless on.is_a? Module
  InjectedLogger.logger_known as: as, refers_to: on unless as.nil?
  targets = [on]
  targets << on.singleton_class unless on.singleton_class?
  targets.each do |target|
    [:inject, :inject!].each do |m|
      target.define_singleton_method m do |*args, **options|
      options.merge! on: on
      InjectedLogger.public_send m, *args, **options
      end
    end
  end
  prelogger = proc do
    # avoid recursion if someone calls logger in the block
    targets.each do |target|
      target.send :remove_method, method_name
    end
    unless InjectedLogger.injected? on: on
      args = blk ? blk.call : nil
      InjectedLogger.inject_logger args, required, on: on
    end
    thislogger = InjectedLogger.send(:logger).[](on)
    required.uniq!
    required -= thislogger.level_info[:supported]
    unless required.empty?
      thislogger.add_levels(*required)
      required -= thislogger.level_info[:supported]
      raise InjectedLogger::UnsupportedLevels.new(required) unless required.empty?
    end
    targets.each do |target|
      target.send :define_method, method_name do
        thislogger
      end
    end
    thislogger.after_hook.call(thislogger) if thislogger.after_hook
    thislogger.send :ready
    thislogger
  end
  targets.each do |target|
    target.send :define_method, method_name, prelogger
  end
end