【问题标题】:How to include a module that extends classmethods and correctly reference class var如何包含扩展类方法并正确引用类 var 的模块
【发布时间】:2013-02-22 19:19:02
【问题描述】:

我的期望在 cmets。

require 'logger'

module Logging
  attr_accessor :logger

  def logger
    return @logger if @logger # allow items to have own loggers
    @@logger ||= Logger.new(STDERR)
    puts "Instance Class REF ID#{@@logger.__id__}"
    puts "Class ID #{self.class.logger.__id__}"
    @@logger
  end

  module ClassMethods
    def logger= logger
      @logger = logger
    end

    def logger
      @logger ||= Logger.new(STDERR)
      puts "Class Instance REF ID #{@logger.__id__}"
      @logger
    end
  end

  def self.included(base)
    base.extend(ClassMethods)
  end
end

class Test

  include Logging

  def wow
    logger.info 'wow'
  end
end

t = Test.new

# should be the same
puts "Loggers are #{t.logger.__id__ == Test.logger.__id__ ? '' : 'not '}the same"

Test.logger = Logger.new('/dev/null')

# should still be the same
puts "Loggers are #{t.logger.__id__ == Test.logger.__id__ ? '' : 'not '}the same"

lg = Test.logger.__id__
t.logger =  Logger.new(STDERR)

# class logger should be same
puts "Class Logger is #{Test.logger.__id__ == lg ? 'still the' : 'not'} same"

# class and instance logger should be different
puts "Loggers are #{t.logger.__id__ == Test.logger.__id__ ? '' : 'not '}the same"

执行时:

➜沙盒irb 1.9.3-p392:001 > 加载“test_l.rb” 实例类 REF ID70203753590760 类实例 REF ID 70203753590500 类 ID 70203753590500 类实例 REF ID 70203753590500 记录器不一样#我希望是一样的...... :( 实例类 REF ID70203753590760 类实例 REF ID 70203753590000 类 ID 70203753590000 类实例 REF ID 70203753590000 记录器不一样#我希望是一样的...... :( 类实例 REF ID 70203753590000 类实例 REF ID 70203753590000 类 Logger 还是一样的 类实例 REF ID 70203753590000 记录器不一样

【问题讨论】:

  • 请考虑编辑标题以使其有用。
  • 您的标题需要反映您提出的问题。照原样,一文不值。
  • 学习为变量和方法使用更好/更具描述性的名称。照原样,从现在起六个月后,您将很难在脑海中保持清醒。不要在主和类级别对实例和类变量和方法重用相同的名称。

标签: ruby include extend


【解决方案1】:

我故意忘记了如何使用@@ 变量,因为它们太混乱而且很少需要。

相反,考虑只使用实例变量,但如果需要,可以委托给类级别:

module Logging
  attr_writer :logger

  def logger
    defined?(@logger) ? @logger : self.class.logger
  end

  module ClassMethods
    def logger=(logger)
      @logger = logger
    end

    def logger
      @logger ||= Logger.new(STDERR)
    end
  end

  def self.included(base)
    base.extend(ClassMethods)
  end
end

class Test
  include Logging

  # ...
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多