Мета-программирование на Ruby, как очистить этот код? - PullRequest
0 голосов
/ 24 февраля 2012

В настоящее время у меня есть код, который повторяется снова и снова, и это выглядит довольно ужасно.Какой лучший способ использовать метапрограммирование Руби для очистки этого?

Повторяющаяся тема, которая у меня есть, выглядит примерно так:

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_logger.info("Wooohooo!") в контроллере или модели без необходимости возвращаться к моему коду инициализации и создавать его там.

Ответы [ 4 ]

8 голосов
/ 24 февраля 2012

Вы можете передать имя регистратора в качестве параметра:

module CustomLogger
    def custom_logger(name)
        @custom_loggers ||= {}
        @custom_loggers[name] ||= Logger.new("log/#{name}.log")
    end
end

Просто включите CustomLogger, где вам нужно, и вы можете сделать:

custom_logger("some3").info("Wooohooo!")
1 голос
/ 24 февраля 2012

Включите это в любые классы, которые получают причудливое поведение логгера:

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
1 голос
/ 24 февраля 2012

Я бы точно не поставил это на Object. Помещение методов в Object просто напрашивается на неприятности.

Может быть, что-то вроде этого подойдет вам:

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.')
0 голосов
/ 24 февраля 2012

Поскольку вы пометили это ruby-on-rails, я предполагаю, что вы находитесь в этой среде, поэтому было бы неплохо последовать его примеру Rails.logger. для именования пространства регистраторов ... Если регистратор rails недостаточно хорошо, что вы могли бы обезопасить это пространство имен вместо Object.

Кроме того, вы можете посмотреть на Уведомления как на возможный способ записи вещей.Смотри http://railscasts.com/episodes/249-notifications-in-rails-3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...