2016-10-30 5 views
-1

Grundsätzlich möchte ich etwas wie folgt aus:ein Verfahren zwischen jedem Methodenaufruf Ausführen

some_method do 
    method1() 
    method2() 
    method3() 
end 

wo, zwischen jedem dieser drei Methoden gäbe es sleep 5 sein, ich will nur nicht sleep 5 nach jedem wiederholen Methodenaufruf. Gibt es eine Möglichkeit, some_method so zu definieren, dass zwischen jedem Methodenaufruf eine bestimmte Methode wie sleep 5 ausgeführt wird? Ich möchte meinen Code nicht verschmutzen, indem ich nach jedem Methodenaufruf eine Reihe von sleep Befehlen einfüge.

+3

Erstellen Sie eine Funktion, die eine Liste von Funktionen übernimmt und jede in einer Schleife ausführt und nach jedem Aufruf einen Ruhezustand hinzufügt. Natürlich ist dies nur möglich, wenn jede Funktion 0 Argumente benötigt, sonst müssten Sie jede Funktion in ein 0-Arity-Lambda einbinden. Idk Ruby, aber wenn es in der Lage ist, könnte ein Makro dies auch tun. – Carcigenicate

Antwort

2

Wenn, wie im Beispiel, die Methoden keine Argumente oder Blöcke annehmen und die Rückgabewerte nicht verwendet werden, können Sie Folgendes tun.

module M 
    def method1 
    puts "method 1" 
    end 
    def method2 
    puts "method 2" 
    end 
    def method3 
    puts "method 3" 
    end 
end 

class A 
    include M 
    def method4 
    puts "method 4" 
    end 
    def execute_methods 
    M.instance_methods.each { |m| send m; sleep 5 } 
    end 
end 

A.new.execute_methods 
    # method 1 
    # method 2 
    # method 3 

Ein Vorteil eines Moduls, einschließlich der Methoden enthalten, ausgeführt werden soll, dass Sie hinzufügen, entfernen oder umbenennen Methoden in dem Modul ohne einen anderen Code zu ändern. Diese Technik könnte möglicherweise nützlich sein, zum Beispiel wenn eine Reihe von Validierungsverfahren ausführt, der jeder Rückkehr true oder false:

def validate(obj) 
    M.instance_methods.all? { |m| send m, obj } 
end 

Dies ist auch ein Beispiel für Verfahren, die verwendet werden, deren Argumente und Rückgabewerte haben.

+0

Ordentlich, aber es ist ein wenig restriktiv, nicht wahr?Jede beliebige Funktion, mit der Sie dies tun möchten, müsste einen Delegaten im Modul haben. – Carcigenicate

+0

@Carcigenicate, ich verstehe nicht, was "Vertreter im Modul" bedeutet. –

+0

Sie müssten einen Wrapper um jede Funktion erstellen, die Sie verwenden möchten, nicht wahr? Wie gesagt, ich wollte das mit der eingebauten Funktion 'map' machen. Ich müsste eine Wrapper-Funktion innerhalb des Moduls erstellen, die die eingebaute 'map' aufruft, oder? – Carcigenicate

0

Anmerkung, ich kenne Ruby nicht, also wird dies in einem geschmackvollen Pseudocode sein, und wird keine "speziellen Eigenschaften" von Ruby verwenden.

Dies ist wahrscheinlich der einfachste Weg, um zu erreichen, was Sie suchen: es

function execute_in_sequence(delay, fs) { 
    foreach(f in fs) { 
     f(); 
     sleep(delay); 
    } 
} 

Dann können Sie verwenden möchten:

function p() { 
    print(1); 
} 

execute_in_sequence(500, 
    [p, p, p] 
); 

Sie auch die explizite Liste loswerden könnte mit variadic Funktionen, die Sie schreiben könnten wie folgt:

execute_in_sequence(500, 
    p, 
    p, 
    p 
); 

In diesem Beispiel p ist ziemlich einfach. Um dies mit Funktionen auszuführen, die Argumente benötigen, müssten Sie die Aufrufe zuerst in ein Lambda umbrechen.

Beachten Sie auch, dass der offensichtliche Fehler ist, dass Sie auf diese Weise keine Werte zurückgeben können. Alle Funktionen müssen nur durch Nebeneffekte funktionieren, was die Nutzung einschränkt.

0

Hier ist eine mögliche some_method Implementierung. Parameter sind die Methodennamen als Symbol (d. H. Method1 für method1()). Wenn ein Block angegeben wird, wird er nach jedem Methodenaufruf ausgeführt.

def method1 
    puts "Method1" 
end 

def method2 
    puts "Method2" 
end 

def method3 
    puts "Method3" 
end 

def some_method(*methods) 
    methods.each{|m| 
    send m 
    yield if block_given? 
    } 
end 

some_method(:method1, :method2, :method3) do 
    puts " Waiting 5 sec." 
    sleep 5 
end 

Es gibt:

Method1 
    Waiting 5 sec. 
Method2 
    Waiting 5 sec. 
Method3 
    Waiting 5 sec. 

Mit einigen Verbesserungen und mehr Logik, können Sie auch Parameter zu den verschiedenen Methoden schicken könnten und speichert, was die Methoden in einem Array zurück.

Verwandte Themen