Получение модуля вызывающей стороны в Ruby

У нас есть код к данным логов в нашем Ruby 1.8.6 веб-приложений. Вы называете его примерно следующим образом:

$log.info("Some text here")

Теперь, в зарегистрированном выводе, я хотел бы включать модуль, где та строка появилась. Я знаю что Kernel#caller даст мне массив, где я могу вытащить номер документа и номер строки, что строка журнала произошла, но я не хочу это. Я хочу модуль, не имя файла. Очевидное решение состоит в том, чтобы изменить строку журнала так, чтобы это читало как:

$log.info("Some text here", self.class.name)

и затем проанализируйте результат. Это не собирается работать, тем не менее, потому что я пытаюсь извлечь эту информацию в случае по умолчанию. Таким образом, мне нужно решение работать, если программист забыл указывать модуль, второй параметр к строке журнала.

Там какой-либо путь состоит в том, чтобы сделать это? В противном случае я должен буду просто суметь обойтись caller массив; большинство наших модулей находится в отдельных каталогах, таким образом, это было бы 80%-м решением.

Больше полного примера, извините незначительные синтаксические ошибки:

в файле log.rb:

module Log
  class Logger
    def info(msg, mod = '')
      puts "Module: #{mod}  Msg: #{msg}"
    end
  end # class Logger
end # module Log
$log = Log::Logger.new

в файле foo.rb:

module Foo
  class Bar
    def do_something
      # Do not pass in self.class.name.
      # We want the output to look like:
      # Module: Foo  Msg: I did something!
      $log.info "I did something!"
    end
  end # class Bar
end #module Foo
6
задан ChrisInEdmonton 6 January 2010 в 22:18
поделиться

2 ответа

Используйте call_stack.

Сначала установите его с помощью RubyGems:

gem install call_stack

Затем измените log.rb на:

require 'rubygems'
require 'call_stack'

call_stack_on

module Log
  class Logger
    def info(msg, mod = '')
        mod = call_stack(2)[0][0] if mod == ''
        puts "Module: #{mod}  Msg: #{msg}"
    end
  end # class Logger
end # module Log
$log = Log::Logger.new

Работает для меня (Ruby 1.8.7).

$ ruby foo.rb
Module: Foo::Bar  Msg: I did something!
3
ответ дан 16 December 2019 в 21:40
поделиться

Наткнулся на это сообщение, когда искал ответ для своих целей.

Не нашел подходящего, поэтому я покопался в исходниках Ruby и собрал расширение. Я связал его как гем - он должен быть установлен без каких-либо проблем, если вы используете Ruby 1.9.1:

sudo gem install sender

Это не будет работать с Ruby 1.8, поскольку 1.8 имеет другую модель отслеживания кадров.

http://rubygems.org/gems/sender

2
ответ дан 16 December 2019 в 21:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: