コードを DRY に保つために、ロギング用の mixin を作成しようと考えました。これはどのように見えるかです:
# Mixin that provides shortcuts for logging methods.
module Logging
def self.included(base)
base.class_exec {
@logger_name = base.to_s
@subloggers = []
@logger = Logger.new(STDOUT)
@logger.level = Logger::FATAL
}
end
def logger=(logger)
@logger = logger
@subloggers.each { |obj| obj.logger = logger }
end
def debug(&block)
@logger.debug(@logger_name, &block)
end
def info(&block)
@logger.info(@logger_name, &block)
end
def warn(&block)
@logger.warn(@logger_name, &block)
end
def error(&block)
@logger.error(@logger_name, &block)
end
def fatal(&block)
@logger.fatal(@logger_name, &block)
end
end
理論的には、私は今これを行うことができるはずです:
class SomeClass
include Logging
def foo_bar
debug { "foo_bar is being executed" }
fatal { "IT'S A TRAP" }
end
end
問題は、明らかにミックスインが含まれる前initialize
に呼び出され、これが失敗することです:
class SomeClass
include Logging
def initialize
@cache = CacheClass.new
@subloggers << @cache # @subloggers is nil
end
end
そして、私はそれを回避する方法を想像することはできません. 私は常にコンストラクターで依存関係を作成します。その時点で Logging mixin を使用できるようにする必要があります。何か案は?