Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Ruby元编程,如何清理这些代码?_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails Ruby元编程,如何清理这些代码?

Ruby on rails Ruby元编程,如何清理这些代码?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我现在有一些代码被一遍又一遍地重复,看起来相当糟糕。使用Ruby的元编程来解决这个问题的最佳方法是什么 我有一个反复出现的主题是这样的: class Object def some_logger @some_logger ||= Logger.new("log/some.log") end def some2_logger @some2_logger ||= Logger.new("log/some2.log") end end 理论上,我只是希望能够在我的R

我现在有一些代码被一遍又一遍地重复,看起来相当糟糕。使用Ruby的元编程来解决这个问题的最佳方法是什么

我有一个反复出现的主题是这样的:

class Object
  def some_logger
    @some_logger ||= Logger.new("log/some.log")
  end

  def some2_logger
    @some2_logger ||= Logger.new("log/some2.log")
  end
end
理论上,我只是希望能够在我的Rails应用程序中调用任意记录器,并将这些日志放到一个单独的、易于识别的文件中。所以我可以随意打电话:


some3\u logger.info(“Wooohooo!”)
在控制器或模型中,而不必返回到我的初始化代码并在那里创建它。

我绝对不会将其放在对象上。在对象上添加方法只是自找麻烦

也许这样的东西适合你的需要:

class MyLogger
  def self.method_missing(method, *args)
    if method =~ /logger$/
      logger_name = method.to_s.split('_').first
      symbol = "@@#{logger_name}".to_sym
      unless class_variable_defined?(symbol)
        class_variable_set(symbol, Logger.new("log/#{logger_name}.log"))
      end
      class_variable_get(symbol)
    end
  end
end

MyLogger.some_logger.info('This is very information.')
MyLogger.test_logger.debug('This goes into a separate file and is for debugging only.')

您可以将记录器名称作为参数传递:

module CustomLogger
    def custom_logger(name)
        @custom_loggers ||= {}
        @custom_loggers[name] ||= Logger.new("log/#{name}.log")
    end
end
只要将CustomLogger包括在您需要的任何位置,您就可以做到:

custom_logger("some3").info("Wooohooo!")

既然您用RubyonRails标记了它,我假设您就在那个环境中,所以按照它的
rails.logger.
来命名记录器的名称也不错。。。如果rails logger不够好,您可以对该名称空间而不是对象进行修补


此外,您还可以将通知视为记录事件的一种可能方式。请参见

在任何获得异想天开的记录器行为的类中包含此项:

module DynoLogger

  def method_missing(method, *args)
    if logger_method? method
      ivar = "@#{method}"
      base = method.to_s
      base[/_logger$/] = ""

      instance_variable_get(ivar) ||
        instance_variable_set(ivar, new_logger(base))
    else
      super
    end
  end

  def respond_to_missing?(method, include_private)
    super || logger_method?(method)
  end

  def logger_method?(method)
    !!(method =~ /_logger$/)
  end

  def new_logger(name)
    Logger.new "log/#{name}.log"
  end

end

请注意,覆盖Response_to_missing很好?(或者,如果您在ruby 1.8中,您是否要覆盖缺少的方法?)?以动态实现方法。应打开代码审阅请求