Was heißt &method(:function)das Zum Beispiel habe ich diese Zeile:
res = integrate(0, 1, a, &method(:function))
Was heißt &method(:function)das Zum Beispiel habe ich diese Zeile:
res = integrate(0, 1, a, &method(:function))
Antworten:
Angenommen, wir haben eine Methode
def add_one(num)
num + 1
end
und eine Reihe von Zeichenfolgen
arr = ["1", "2"]
Wir wollen mapdie Liste der Strings zu ihren entsprechenden Ausgaben von add_one.
Zu Beginn können wir anrufen
nums = arr.map(&:to_i)
Das ist das Gleiche wie
nums = arr.map do |str|
str.to_i
end
Sie können sehen, was Karte (&: Name) in Ruby bedeutet. Weitere Informationen hierzu.
Es funktioniert jedoch nicht, Folgendes anzurufen:
nums.map(&:add_one)
Warum? Weil Zahlen keine eingebaute Methode haben add_one. So bekommen Sie eine NoMethodError.
Anstatt nur einen Methodennamen anzugeben :add_one , können Sie eine gebundene Methode übergeben method(:add_one) :
nums.map(&method(:add_one))
Anstatt dass jede Zahl als Empfänger für die add_oneMethode verwendet wird, werden sie jetzt als Argumente verwendet . Es ist also im Wesentlichen dasselbe wie:
nums.map do |num|
add_one(num)
end
Um ein weiteres Beispiel zu nennen, vergleichen Sie Folgendes:
[1].map(&:puts)
# this is the same as [1].map { |num| num.puts }
# it raises NoMethodError
[1].map(&method(:puts))
# this is the same as [1].map { |num| puts num }
# it prints 1 successfully
Object#methodeine Bindung zurück Method , keine UnboundMethod. Die Methode ist an einen Empfänger gebunden , weil Sie sie auf einer Instanz aufrufen und somit wissen, was sie selfist, während sie eine Module#instance_methodzurückgibt, UnboundMethodweil sie nicht wissen kann, mit welcher Instanz sie verwendet werden soll.
.instance_methodweil ich gerade durch (fehlerhafte) Erinnerung
method(:function)ist eine Nachricht, die an den impliziten Empfänger (dh ) gesendet wird (manchmal auch als Methodenaufruf bezeichnetself ). Es sendet die Nachricht methodan den impliziten Empfänger (dh self) und übergibt sie :functionals einziges Argument.
:functionist ein SymbolLiteral, dh es ist die wörtliche Notation von a Symbol. Symbolist ein Datentyp, der "den Namen von etwas" darstellt.
Der kaufmännische Und- &Operator mit unärem Präfix "rollt" a Procin einen Block ab . Dh es erlaubt Ihnen, einen zu übergeben, Procwo ein Block erwartet wird. Wenn das Objekt noch kein Objekt ist Proc, wird ihm die to_procNachricht gesendet , damit es sich selbst in ein Objekt konvertieren kann Proc. (Der Operator ist nur in einer Argumentliste legal und nur für das letzte Argument. Es ist das Dual des &Siegels in einer Parameterliste, das einen Block in ein ProcObjekt "rollt" .)
Procist ein Datentyp, der ausführbaren Code darstellt. Es ist Rubys Kernbibliotheksklasse für erstklassige Unterprogramme.
Rufen Sie also die methodMethode selfmit :functionals Argument auf, rufen Sie to_procden Rückgabewert auf, "rollen" Sie das resultierende ProcObjekt in einen Block ab und übergeben Sie diesen Block an den Aufruf an, integrateals hätten Sie so etwas geschrieben
res = integrate(0, 1, a) do
# something
end
Die methodMethode hier ist höchstwahrscheinlich die Object#methodMethode, die ein gebundenes Method Objekt zurückgibt .
Alles in allem ist dies also etwas äquivalent zu
res = integrate(0, 1, a) do |*args, &block|
function(*args, &block)
end
Aber ausgedrückt in dem, was allgemein als punktfreier Stil bezeichnet wird .