【问题标题】:Set class variable from module从模块设置类变量
【发布时间】:2016-02-08 14:22:31
【问题描述】:

我想为我的应用创建单独的日志。我创建了以下模块:

module MyApp
  module MyLog
    def self.included(base)
      base.extend(ClassMethods)
    end

    module ClassMethods
      def logger
        @@logger ||= Logger.new("#{Rails.root}/log/#{self.name.underscore}.log")
      end
    end
  end
end

然后,在我的任何模型中,我都可以添加:

include MyApp::MyLog

并将其用作(日志文件将出现在.../log/cat.log):

Cat.logger.info 'test'

我尝试在CatDog 模型上使用这种方法included,我得到了这个结果:

Cat.new.logger
# => #<Logger:0x007fe4516cf0b0 @progname=nil, ... @dev=#<File:/.../log/cat.log>, ... 
Dog.new.logger
# => #<Logger:0x007fe4516cf0b0 @progname=nil, ... @dev=#<File:/.../log/cat.log>, ... (the same)

如果我首先尝试将我的记录器用于Dog 模型,我将有一个名为dog (/dog.log) 的日志文件。

如何使用正确的初始化记录器从模块中为每个类设置类变量@@logger

【问题讨论】:

    标签: ruby-on-rails ruby logging


    【解决方案1】:

    不要使用类变量,使用附加到类的instance_variable

    module MyApp
      module MyLog
    
        def self.included(base)
          base.extend(ClassMethods)
        end
    
        module ClassMethods
          def logger
            @logger ||= Logger.new("#{Rails.root}/log/#{self.name.underscore}.log")
          end
        end
    
      end
    end
    

    示例:

    module A
      def self.included(base)
        base.extend ClassMethods
      end
    
      module ClassMethods
    
        def logger
          puts @logger
          @logger ||= name
        end
      end
    end
    
    class B
      include A
    end
    
    class C
      include A
    end
    
    B.logger
    #
    B.logger
    # B
    C.logger
    #
    B.logger
    # B
    C.logger
    # C
    

    第一次调用方法是nil,因此是空行,第二次调用方法的值等于类名B,如果在新类上调用它又是nil,检查也是这个答案

    Ruby class instance variable vs. class variable

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      相关资源
      最近更新 更多