获得来电课程

时间:2013-10-30 10:39:33

标签: ruby

我正在编写Logger并遇到自动添加类名的问题,我从中调用了print_log方法。 例如:

class Logger
  def self.print_log(string)
    puts Time.now.strftime('%T | ') + *caller_class_name_here* + ' - ' + string 
  end
end

class MyClass
  def initialize
    Logger.print_log 'called .new() method'
  end
end

作为调用MyClass.new方法的结果,我想在输出中看到:

  14:41:23 | MyClass - 名为.new()方法

我确定可以使用caller,但却无法找到

3 个答案:

答案 0 :(得分:6)

你可以使用那样的模块(Rails风格):

module Loggable
  extend ActiveSupport::Concern

  def log_prefix
    @log_prefix ||= (self.class == Class ? "#{self.to_s}" : "#{self.class.to_s}").freeze
  end

  included do
    [:debug, :info, :warn, :error, :fatal].each do |level|
      define_method level do |str = nil|
        caller = caller_locations(1,1)[0].label
        prefix = "[#{log_prefix}##{caller}] "
        prefix << level.to_s.upcase[0]
        str = "#{prefix}: #{str}"
        puts str if ENV["DEBUG"]
        Rails.logger.send(level, str)
      end
    end
  end
end

你的代码将是:

class MyClass
  include Loggable
  extend Loggable

  def instance_method
    debug "Hello"
  end

  def self.klass_method
    debug "Klass"
  end
end

答案 1 :(得分:4)

我不确定是否可以获得您想要的类名。我会为此创建一个记录器实例,您可以在创建它时传入类名。

class Logger
  def initialize(class_name)
    @class_name = class_name
  end

  def print_log(message)
    puts Time.now.strftime('%T | ') + @class_name + ' - ' + message
  end
end

class MyClass
  def initalize
    @logger = Logger.new self.class.name
    @logger.print_log 'called .new() method'
  end
end

比您想要的更详细,但显式代码易于理解。

对于任何认真的工作,我建议使用standard library logger。您可能必须将其包装在您自己的调用中以获取所需的日志消息,但您将获得日志轮换和文件处理。

答案 2 :(得分:2)

在与caller进行一段时间的讨论之后,它可能不适合你,而caller_locations也不会。可以跟踪在当前线程上实例化的最后一个对象的类,例如

class Class
  alias :_new :new
  def new *args
    Thread.current.thread_variable_set :classes, ((Thread.current.thread_variable_get(:classes) || []) << self).last(10)
    _new *args
  end
end

这保留了最后10个对象的类,但这并不等同于层次结构,例如

class X
  def initialize
    puts Thread.current.thread_variable_get(:classes)
  end
end

class Y
end

class Z
  def initialize
    @y = Y.new
    @x = X.new
  end
end

X.new输出以下内容(在控制台会话中)

RubyToken::TkNL
RubyToken::TkEND
RubyToken::TkNL
RubyToken::TkCONSTANT
RubyToken::TkDOT
RubyToken::TkIDENTIFIER
RubyToken::TkNL
Y
Z
X