1

私の期待はコメントにあります。

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'
インスタンスクラスREFID70203753590760
クラスインスタンスREFID70203753590500
クラスID70203753590500
クラスインスタンスREFID70203753590500

ロガーは同じではありません#私は同じだと思っていました... :(

インスタンスクラスREFID70203753590760
クラスインスタンスREFID70203753590000
クラスID70203753590000
クラスインスタンスREFID70203753590000

ロガーは同じではありません#私は同じだと思っていました... :(

クラスインスタンスREFID70203753590000
クラスインスタンスREFID70203753590000

クラスロガーはまだ同じです

クラスインスタンスREFID70203753590000

ロガーは同じではありません
4

1 に答える 1

6

@@変数は非常に紛らわしく、めったに必要とされないため、意図的に変数の使用方法を忘れてしまいました。

代わりに、インスタンス変数のみを使用することを検討しますが、必要に応じてクラス レベルまでデリゲートします。

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
于 2013-03-07T14:46:21.047 に答える