我有一个在默认记录器中加载的Log类,并添加了一些方法,所以我可以有一些语法糖;问题是Logger从另一个类中获取文件位置和名称log.progname
,该类充当所有Info(配置选项,常量等)信息的中心位置。
这是一个问题,因为我想让Log类可重用。如何在不改变行为的情况下从Info类中解除Log类。
我的班级目前看起来像:
class Log
F = File.open(Info[:logfile], 'a')
F.sync = true
@l = Logger.new(F).tap do |log|
log.progname = Info[:short_name]
end
class << self
def set_level(level)
@l.level = Logger.const_get level.upcase
end
def display(message, level)
puts message unless level == :fatal
end
def []=(level,message)
case message.class.to_s
when 'String'
display message, level
@l.send level, message
when 'Array'
message.each do |line|
display line, level
@l.send level, line
end
when 'Hash'
message.each do |level,line|
display line, level
@l.send level, line
end
else
raise TypeError, "method expects Hash,String or Array, message was of type #{message.class}"
end
end
end
end
我能想到的唯一方法是将它从单例转换为实例化对象,然后在初始化时将值传递给它, 但是我宁愿把它当作一个单身人士,所以有什么建议吗?
我想我真正要求的是关于如何将这个课程与另一个课程分开的建议,更重要的是将来如何去做。
答案 0 :(得分:0)
你可能不需要Singleton。 这是你可以做的:
class MyLogger
def initialize(info)
@file = File.open(info[:logfile], 'a')
@file.sync = true
@l = Logger.new(F).tap do |log|
log.progname = info[:short_name]
end
end
# ...
end
Log = MyLogger.new(Info)
# Now you can inject info and even have multiple logs
Log2 = MyLogger.new(Info2)
另一个好处是你可以控制何时初始化Log而不是在加载类时初始化它,这可能是一件坏事,因为你正在打开一个文件。