2013-02-22 12 views
6

Ich benutze g einen Logger in allen meinen Klassen. Ich möchte jede msg mit Klassennamen und Methodennamen beginnen wie folgt:implementieren Sie eine Schiene Before_filter in Ruby ohne Schienen

Class_name::Method_name 

das ist, was ich jetzt tue:

class FOO 

def initialize 
end 

def bar 
    msg_prefix = "#{self.class}::#{__method__}" 
    ... some code ... 
    @logeer = "#{msg_prefix} msg ..." 
end 

def bar2 
    msg_prefix = "#{self.class}::#{__method__}" 
    ... some code 2 ... 
    @logeer = "#{msg_prefix} msg2 ..." 
end 

end 

ich eine before_filter wie in Schienen verwendet werden soll verhindern Duplizität, Ich benutze sinatra aber die Klassen sind einfach alt ruby 1.9.3 Klassen

Ideen ??

+0

können Sie activerecord mit sinatra verwenden https://github.com/janko-m/sinatra-activerecord – AJcodez

Antwort

5

Sie einen Rückruf an einem Verfahren erhalten können wird erstellt mit Module#method_added, alias die alte Methode, dann definieren Sie eine neue Methode, die zuerst die Methode before_filter aufruft. Hier ist mein (sehr) rau erstes Konzept:

module Filter 
    def before_filter name 
    @@filter = name 
    end 

    def method_added name 
    return if @filtering # Don't add filters to original_ methods 
    return if @@filter == name # Don't filter filters 
    return if name == :initialize 

    @filtering = true 

    alias_method :"original_#{name}", name 
    define_method name do |*args| 
     self.send @@filter, name 
     self.send :"original_#{name}", *args 
    end 
    @filtering = false 
    end 
end 

class FilterTest 
    extend Filter 
    before_filter :prepare_logs 

    def baz 
    puts "#{@msg_prefix} message goes here" 
    end 

    def prepare_logs name 
    @msg_prefix = "#{self.class}::#{name}" 
    end 
end 

ft = FilterTest.new 
ft.baz 

Durch die Verwendung von __method__ wie Sie in create_prefix waren, werden Sie den Namen des Filtermethode erhalten, nicht die ursprüngliche Methode, so dass Sie den Namen der Methode passieren müssen in Es könnte andere Lösungen geben, um das ein bisschen sauberer zu machen.

+0

danke Zaius, das hat tatsächlich den Trick gemacht, aber ich habe es in der Superklasse implementiert, und es hat für 1. die Superklasse selbst funktioniert, 2. es ist Kind, 3. für seine Enkelsöhne gab es mir eine 'Uncaught'-Ausnahme: Stapelebene zu tief "Ich frage mich, warum .. – WebQube

+0

Nun .. es ist eine Art von hacky Lösung, so dass mich nicht überrascht. Fügen Sie Ihren Code und die Fehlermeldung auf gist oder etwas und ich kann Ihnen sagen, warum es bricht. – zaius

+0

sicher, hier ist es. Die Instanzen sind am Ende. [gist] (https://gist.github.com/ohadpartuck/5070783) – WebQube

1

Sie ActiveModel::Callbacks verwenden können before_filter -ähnlichen Verhalten im Klar Ruby-Klassen zu bekommen (wenn auch vielleicht in Ihrem Fall es nur für die Ausführung einer Zeile Overkill ist):

require 'active_model' 

class FOO 
    extend ActiveModel::Callbacks 

    define_model_callbacks :baz, only: :before 

    before_baz :create_prefix 

    def initialize 
    end 

    def bar 
    run_callbacks :baz do 
     ... some code ... 
     @logeer = "#{@msg_prefix} msg ..." 
    end 
    end 

    def bar2 
    run_callbacks :baz do 
     ... some code 2 ... 
     @logeer = "#{@msg_prefix} msg2 ..." 
    end 
    end 

    private 

    def create_prefix 
     @msg_prefix = "#{self.class}::#{__method__}" 
    end 
end 
+0

hallo Paul, danke für die Antwort, aber ich bin auf der Suche nach einer Möglichkeit, es die genaue Weise zu verwenden Schienen, eins line 'before_filter: do_prefix_msg', die automatisch vor jeder Funktion ausgeführt wird (sofern nicht anders angegeben) – WebQube

+0

Ich denke, dass die Verwendung von' ActiveModel :: Callbacks 'der einfachste Weg ist, den gewünschten Effekt zu erhalten, ohne die angemessene Menge Code neu implementieren zu müssen das steht hinter den Callbacks von Rails (https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/abstract_controller/callbacks.rb). Ich hatte dieses Problem vor einiger Zeit bei einem meiner eigenen Projekte und konnte keine bessere Lösung finden als 'ActiveModel :: Callbacks'. Aber in der Hoffnung, dass es noch einen anderen Weg gibt, den jemand anders kennt, werde ich die Frage +1 geben. –