Ruby需要帮助解耦类

时间:2015-01-18 17:14:06

标签: ruby

我有一个在默认记录器中加载的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

我能想到的唯一方法是将它从单例转换为实例化对象,然后在初始化时将值传递给它, 但是我宁愿把它当作一个单身人士,所以有什么建议吗?

我想我真正要求的是关于如何将这个课程与另一个课程分开的建议,更重要的是将来如何去做。

1 个答案:

答案 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而不是在加载类时初始化它,这可能是一件坏事,因为你正在打开一个文件。