Ich versuche ein bisschen mit Ruby herumzuspielen. Daher versuche ich, die Algorithmen (in Python angegeben) aus dem Buch "Programming Collective Intelligence" Ruby zu implementieren.
In Kapitel 8 übergibt der Autor eine Methode a als Parameter. Dies scheint in Python zu funktionieren, aber nicht in Ruby.
Ich habe hier die Methode
def gaussian(dist, sigma=10.0)
foo
end
und möchte dies mit einer anderen Methode aufrufen
def weightedknn(data, vec1, k = 5, weightf = gaussian)
foo
weight = weightf(dist)
foo
end
Ich habe nur einen Fehler
ArgumentError: wrong number of arguments (0 for 1)
quelle
foo.bar(a,b)
mit Senden tun möchten , ist esfoo.send(:bar, a, b)
. Der splat (*) -Operator ermöglicht es Ihnen,foo.send(:bar, *[a,b])
wenn Sie feststellen, dass Sie ein beliebig langes Array von Argumenten haben möchten - vorausgesetzt, dieDie Kommentare zu Blöcken und Prozessen sind insofern korrekt, als sie in Ruby üblicher sind. Sie können jedoch eine Methode übergeben, wenn Sie möchten. Sie rufen
method
auf, um die Methode abzurufen und.call
aufzurufen:quelle
method( :<name> )
nur einmal aufrufen, wenn Sie Ihren Methodennamen in ein aufrufbares Symbol konvertieren. Sie können dieses Ergebnis in einer Variablen oder einem Parameter speichern und es von nun an wie jede andere Variable anSomewhereElse.method(:method_name)
. Das ist ziemlich toll!:func.class
aber das ist nur einsymbol
Sie können eine Methode als Parameter mit
method(:function)
way übergeben. Unten ist ein sehr einfaches Beispiel:quelle
method_with_function_as_param(Class.method(:method_name),...)
und nichtmethod(:Class.method_name)
method
. Ich habe meinen Tag gemacht, aber ich denke, deshalb bevorzuge ich funktionale Sprachen. Ich muss keine solche Akrobatik machen, um das zu bekommen, was Sie wollen. Wie auch immer, ich grabe RubinDer normale Ruby-Weg, dies zu tun, ist die Verwendung eines Blocks.
Es wäre also so etwas wie:
Und verwendet wie:
Dieses Muster wird in Ruby häufig verwendet.
quelle
Sie können den
&
Operator für dieMethod
Instanz Ihrer Methode verwenden, um die Methode in einen Block zu konvertieren .Beispiel:
Weitere Informationen finden Sie unter http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html
quelle
Sie müssen die Methode "call" des Funktionsobjekts aufrufen:
EDIT: Wie in den Kommentaren erläutert, ist dieser Ansatz falsch. Es würde funktionieren, wenn Sie Procs anstelle normaler Funktionen verwenden.
quelle
weightf = gaussian
in der Arg-Liste tut, versucht er tatsächlichgaussian
, das Ergebnis als Standardwert für weightf auszuführen und zuzuweisen. Für den Anruf sind keine Argumente und Abstürze erforderlich. Weightf ist also noch nicht einmal ein Proc-Objekt mit einer Aufrufmethode.Ich würde empfehlen, kaufmännisches Und zu verwenden, um Zugriff auf benannte Blöcke innerhalb einer Funktion zu erhalten. Wenn Sie den Empfehlungen in diesem Artikel folgen, können Sie so etwas schreiben (dies ist ein echter Ausschnitt aus meinem Arbeitsprogramm):
Danach können Sie diese Funktion folgendermaßen aufrufen:
Wenn Sie Ihre Auswahl nicht filtern müssen, lassen Sie den Block einfach weg:
Soviel zur Kraft der Ruby-Blöcke.
quelle
Sie können auch "eval" verwenden, die Methode als Zeichenfolgenargument übergeben und sie dann einfach in der anderen Methode auswerten.
quelle
eval
kann der Code beliebigen Code ausführen, sodass er extrem anfällig für verschiedene Angriffe ist.