2013-10-30 49 views
8

我正在寫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的 - 所謂的。新的()方法

我敢肯定,這可以利用caller做的,但目前還找不到如何

+1

http://stackoverflow.com/questions/4116525/sender-class-in-r uby可能在這裏是答案...( – Hroft

回答

1

經過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 
+0

小心管理你的線程,否則它的內存佔用將增長 –

3

我不知道是否有可能得到的類名狀你要。我將爲此創建一個記錄器實例,在創建它時可以在類名中傳入此實例。

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。您可能需要將它封裝在自己的調用中才能獲取所需的日誌消息,但您應該按照原樣進行日誌旋轉和文件處理。

4

您可以使用類似(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 
+0

'caller_locations'需要Ruby 2.0 –