0

我想我会做一个混合记录来保持我的代码干燥。这是它的外观:

# 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

问题是显然在包含 mixins之前initialize调用了它,导致失败:

class SomeClass
  include Logging

  def initialize
    @cache = CacheClass.new
    @subloggers << @cache   # @subloggers is nil
  end
end

我无法想象任何方式。我总是在构造函数中创建我的依赖项,并且我需要 Logging mixin 在那时可用。有任何想法吗?

4

2 回答 2

0

这是错误的:

问题是显然在包含 mixin 之前调用了 initialize,导致失败:

与你写的相反,initialize不叫。@subloggers没有为SomeClass实例初始化。您是否认为@subloggers分配Logging.included(base)的变量与您从构造函数@subloggers访问的变量相同?SomeClass情况不应该如此。在创建实例本身之前不能创建实例变量。

于 2013-06-11T10:51:14.630 回答
0

我认为当您混入该类时,这些变量将成为该类的实例变量。不要与类变量或常规实例变量混淆。看看这个小小的 irb 对话:

1.9.3p194 :012 > Foo 类
1.9.3p194:013?> def self.bar
1.9.3p194:014?> @bar
1.9.3p194:015?> 结束
1.9.3p194 :016?> def self.bar=(x)
1.9.3p194:017?> @bar=x
1.9.3p194:018?> 结束
1.9.3p194:019?> def self.show
1.9.3p194:020?> 放@bar
1.9.3p194:021?> 结束
1.9.3p194:022?> 结束
 => 无
1.9.3p194 :023 > Foo.bar=5
 => 5
1.9.3p194 :024 > Foo.bar
 => 5
1.9.3p194:025 > Foo.show
5
 => 无
1.9.3p194:026 > a=Foo.new
 => #<Foo:0x007fe9038e5dc0>
1.9.3p194:029 > a.instance_variables
 => []
1.9.3p194:030 > a.class.instance_variables
 => [:@bar]

比较您的课程的结果:

SomeClass.instance_variables
SomeClass.new.instance_variables
SomeClass.new.class.instance_variables
于 2013-06-11T12:45:01.693 回答