2013-03-07 9 views
1

我的期望值在評論中。如何添加一個擴展classmethods並正確引用類的模塊var

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" 

執行時:

 
➜ sandbox irb 
1.9.3-p392 :001 > load 'test_l.rb' 
Instance Class REF ID70203753590760 
Class Instance REF ID 70203753590500 
Class ID 70203753590500 
Class Instance REF ID 70203753590500 

Loggers are not the same # I expected to be same... :(

Instance Class REF ID70203753590760 
Class Instance REF ID 70203753590000 
Class ID 70203753590000 
Class Instance REF ID 70203753590000 

Loggers are not the same # I expected to be same... :(

Class Instance REF ID 70203753590000 
Class Instance REF ID 70203753590000 

Class Logger is still the same 

Class Instance REF ID 70203753590000 

Loggers are not the same 
+2

請考慮編輯標題變得有用。 – Anna 2013-03-07 14:48:47

+0

您的標題需要反映您提問的問題。因爲它是毫無價值的。 – 2013-03-07 14:56:52

+0

學習爲變量和方法使用更好/更具描述性的名稱。就目前而言,六個月後,你將很難保持頭腦清醒。不要在main和class級別重用實例和類變量AND方法的相同名稱。 – 2013-03-07 15:01:00

回答

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