Получение модуля звонилки в Ruby - PullRequest
6 голосов
/ 07 января 2010

У нас есть код для регистрации данных в нашем веб-приложении 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

Ответы [ 3 ]

3 голосов
/ 10 сентября 2011

Миксин решает специфические требования ОП (тем временем +1 к Ашеру за решение общего дела "кто меня назвал!").

module Log
  module Logger
    def info(msg)
      puts "Module: #{self}  Msg: #{msg}"
    end
  end # class Logger
end # module Log

module Foo
  class Bar
    include Log::Logger
    def do_something
      # Do not pass in self.class.name.
      # We want the output to look like:
      # Module: Foo  Msg: I did something!
      info "I did something!"
    end
  end # class Bar
end # module Foo

foobar = Foo::Bar.new
foobar.do_something
3 голосов
/ 07 января 2010

Использование 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!
2 голосов
/ 24 июня 2010

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

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

sudo gem install sender

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

http://rubygems.org/gems/sender

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