2009-09-14 5 views
16

Ich möchte mehrere verschiedene Methoden in einem Array in Ruby speichern. Angenommen, ich möchte die doppelte type Methode speichern:Methodenzeiger in Ruby

[type, type] 

nicht speichert zwei Einträge von type in einem Array; Es führt type zweimal aus und speichert die Ergebnisse in dem Array. Wie verweise ich explizit auf das Methodenobjekt selbst?

(dies ist nur eine vereinfachte Version von dem, was ich wirklich will.)

EDIT: auf dem zweiten Gedanken, es stört mich, dass die Lösung unter vermeidet das Problem, indem Sie den Namen des Verfahrens vorgeschlagen. Wie übergibt man das Methodenobjekt selbst? Was passiert beispielsweise, wenn Sie [: type,: type] an eine Methode übergeben, die eine alternative Auflösung für den Typ aufweist? Wie können Sie das Typmethodenobjekt selbst übergeben?

Antwort

31

Wenn Sie eine Methode, anstatt das Ergebnis einer Methode aufrufen oder einfach nur die Nachricht speichern möchten Sie senden würde aufrufen Sie müssen die method-Methode für das besitzende Objekt verwenden. So zum Beispiel

"hello".method(:+) 

die + Methode des Objekts „Hallo“ zurückkehren, so dass, wenn Sie es mit dem Argument „Welt“ nennen, werden Sie „Hallo Welt“ bekommen.

+0

[method (: type), method (: type)] – jrhicks

+0

@jrhicks: Nur wenn die Methoden zu self gehören. – Chuck

+0

Erstes SO Ruby Abzeichen - Herzlichen Glückwunsch! –

1
[:type, :type].collect { |method_name| self.send(method_name) } 

Alternativ kann, wenn das Verfahren ist Teil eines Objekts:

method = obj.method(:type) 
values = [method.call, method.call] 
+0

das scheint für mich nicht zu funktionieren - es ergibt nur "[Object, Object]'. – Peter

+0

Der erste Teil der Antwort wurde im Grunde von irb kopiert, also nehme ich an, dass die Vereinfachung Ihrer Situation es vermasselt. –

+0

Sieht gut aus für mich. Der Objekttyp ist Object ... Wahrscheinlich möchten Sie 'self.send (method_name)', damit die Methode auf Ihr Objekt und nicht auf das globale Object-Objekt angewendet wird. –

11

Wenn Sie über Methodenverweise in Ruby nachdenken, machen Sie es falsch.

Es gibt eine integrierte Methode in Ruby namens method. Es wird eine Proc-Version der Methode zurückgegeben. Es ist jedoch kein Verweis auf die ursprüngliche Methode; Bei jedem Aufruf von method wird ein neuer Proc erstellt. Das Ändern der Methode wirkt sich z. B. nicht auf den Prozess aus.

def my_method 
    puts "foo" 
end 

copy = method(:my_method) 

# Redefining 
def my_method 
    puts "bar" 
end 

copy.call 
# => foo 

Wenn Sie Teile des Codes speichern möchten, und wollen nicht regelmäßig Methoden, Procs Gebrauch verwenden.

stack = [proc { do_this }, proc { do_that }] 
stack.each {|s| s.call } 
+0

Wie ich in den Kommentaren zu meiner Antwort gesagt habe, sollte es genau so funktionieren. Wenn Sie die Methode nicht ändern, ersetzen Sie die Methode. Offensichtlich bezieht sich ein Verweis auf die alte Methode immer noch auf die alte Methode, so wie eine Referenz auf einen alten Instanzvariablenwert sich immer noch auf die alte bezieht, auch wenn Sie der Instanzvariablen einen neuen Wert geben. Wenn Sie eine dynamische Methode anstatt eine bestimmte Methode speichern möchten, möchten Sie stattdessen eine Nachricht senden. – Chuck