2012-02-24 18 views
0

目前,我有一些代碼正在被重複一遍又一遍,它看起來相當可怕。使用Ruby的元編程來清理這個問題的最好方法是什麼?Ruby元編程,這個代碼如何清理?

一個反覆出現的主題,我已經是這樣的:

class Object 
    def some_logger 
    @some_logger ||= Logger.new("log/some.log") 
    end 

    def some2_logger 
    @some2_logger ||= Logger.new("log/some2.log") 
    end 
end 

從理論上講,我只是想能夠調用我的整個Rails應用程序的任意記錄,並將這些記錄到一個單獨的,易於識別文件。因此,我可以隨意將調用:在控制器或模型

some3_logger.info("Wooohooo!"),而不必回到我的初始化代碼,有創建它。

+0

代碼審查的要求應該是http://codereview.stackexchange.com – 2012-02-24 17:18:11

回答

8

你可以通過記錄器名稱作爲參數:

module CustomLogger 
    def custom_logger(name) 
     @custom_loggers ||= {} 
     @custom_loggers[name] ||= Logger.new("log/#{name}.log") 
    end 
end 

就包括CustomLogger你需要的地方,你可以這樣做:

custom_logger("some3").info("Wooohooo!") 
1

我絕對不會把這個對象。將方法放在Object上只是要求麻煩。

也許會有這樣的滿足您的需求:

class MyLogger 
    def self.method_missing(method, *args) 
    if method =~ /logger$/ 
     logger_name = method.to_s.split('_').first 
     symbol = "@@#{logger_name}".to_sym 
     unless class_variable_defined?(symbol) 
     class_variable_set(symbol, Logger.new("log/#{logger_name}.log")) 
     end 
     class_variable_get(symbol) 
    end 
    end 
end 

MyLogger.some_logger.info('This is very information.') 
MyLogger.test_logger.debug('This goes into a separate file and is for debugging only.') 
0

既然你用ruby-on-rails標記了這個,我假設你在那個環境中,s Ø它不會壞遵循的Rails.logger.的例子來命名空間中的記錄器...如果軌道記錄器是不夠的,你可能猴子補丁namesspace的對象,而不是良好。

另外,您可以將通知視爲記錄事物的可能方式。見http://railscasts.com/episodes/249-notifications-in-rails-3

1

在得到異想天開的記錄行爲的任何類包括這樣的:

module DynoLogger 

    def method_missing(method, *args) 
    if logger_method? method 
     ivar = "@#{method}" 
     base = method.to_s 
     base[/_logger$/] = "" 

     instance_variable_get(ivar) || 
     instance_variable_set(ivar, new_logger(base)) 
    else 
     super 
    end 
    end 

    def respond_to_missing?(method, include_private) 
    super || logger_method?(method) 
    end 

    def logger_method?(method) 
    !!(method =~ /_logger$/) 
    end 

    def new_logger(name) 
    Logger.new "log/#{name}.log" 
    end 

end 
+0

請注意,這是很好的覆蓋respond_to_missing? (或者的respond_to?如果你在紅寶石1.8),如果你要重寫的method_missing?即時實現方法。 – 2012-02-24 17:01:09