我正在编写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
,但却无法找到
答案 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