2013-03-07 54 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