2013-10-30 2 views
8

Logger를 쓰고 있는데 print_log 메소드를 호출 한 클래스 이름을 자동으로 추가하는 데 문제가 있습니다. 이 같은 예를 들어 뭔가 :호출자 클래스 가져 오기

I 출력에보고 싶어 MyClass.new 메소드를 호출의 결과
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 

:

14시 41분 23초 | MyClass에 - .new를 호출() 메소드

나는 클래스 이름 등을 얻을 수있는 경우

+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

나는 확실하지 않다 방법을 찾을 수 없습니다 아직 caller을 사용하여이 작업을 수행하는 것이 가능하지만, 확신 네가 원해. 이 클래스를 생성 할 때 클래스 이름을 전달할 수있는 로거 인스턴스를 생성합니다.

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

당신은 그 (레일 스타일) 등의 모듈을 사용할 수 있습니다 출력 :

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을 필요로합니다 –