关于rails上的ruby:从模块设置类变量

Set class variable from module

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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

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

1
include MyApp::MyLog

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

1
Cat.logger.info 'test'

我尝试在CatDog模型上使用这种方法,结果是:

1
2
3
4
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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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类实例变量与类变量