Wie rufe ich eine Methode, die ein hash-Wert?
Zuvor fragte ich eine clevere Art und Weise zum ausführen einer Methode auf einem bestimmten Zustand "Ruby-ein cleverer Weg, um eine Funktion ausführen, die auf eine Bedingung."
Lösungen und response-Zeit war toll, aber bei der Umsetzung, dass ein hash-Wert lambdas bekommt hässlich sehr schnell. So begann ich zu Experimentieren.
Der folgende code funktioniert:
def a()
puts "hello world"
end
some_hash = { 0 => a() }
some_hash[0]
Aber wenn ich wickeln Sie diese in eine Klasse, es funktioniert:
class A
@a = { 0 => a()}
def a()
puts "hello world"
end
def b()
@a[0]
end
end
d = A.new()
d.b()
Ich kann nicht sehen, warum sollte es aufhören zu arbeiten, kann jeder jeden schlagen, wie es funktionieren?
InformationsquelleAutor | 2009-07-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
dass code, der nicht funktioniert. es führt
a
an der Zeit, zu der es Hinzugefügt wird, um den hash, nicht, wenn es abgerufen wird, aus dem hash (versuchen Sie es in irb).Es funktioniert nicht in der Klasse, weil es keine
a
- Methode, definiert in der Klasse (Sie schließlich eine Methode definierena
auf die Instanz.Versuchen tatsächlich mit lambdas wie
statt
Ist der code messier in einen lambda-Ausdruck, als wäre es in einer Methode?
dann übergeben Sie der Methode die Namen als Symbole und Sie verwenden senden oder das Symbol#to_proc.
es wäre identisch, aber die Verpackung der code in den Methoden dann referenzieren Sie diese in der hash-scheint eine schönere Lösung.
haben Sie in Betracht gezogen, die Schaffung einer Methode der Klasse, die könnte nehmen Sie einen block und fügen Sie es als einen lambda-Ausdruck, um Ihren hash und dann einfach bei Bedarf in Ihrer Klasse Körper.
InformationsquelleAutor Ben Hughes
Erste von allen, Sie werden nicht setzen ein lambda in der hash. Sie setzen die Ergebnis des Aufrufs
a()
im aktuellen Kontext.Angesichts dieser Informationen, überlegen, was der code in der Klasse bedeutet. Der Kontext der definition einer Klasse ist die Klasse. So definieren Sie eine Instanz-Methode aufgerufen
a
, und ordnen Sie eine Klasse-Instanz-variable ein hash enthält das Ergebnis des Aufrufsa
im aktuellen Kontext. Der aktuelle Kontext ist die Klasse A, und Klasse A hat auch keine Methode einer Klasse aufgerufena
, so dass Sie versuchen, das Ergebnis einer nicht vorhandenen Methode gibt. Dann in der Instanz-Methodeb
Sie versuchen, Zugriff auf eine Instanz-variable namens@a
- aber gibt es nicht. Die@a
in der Klasse definiert Kontext gehört zu der Klasse selbst, nicht eine bestimmte Instanz.Also zunächst einmal, wenn Sie möchten, eine lambda, die Sie brauchen, um einen lambda-Ausdruck. Zweitens müssen Sie klar sein über den Unterschied zwischen einer Klasse und einer Instanz der Klasse.
Wenn Sie möchten, machen Sie eine Liste von Methodennamen aufgerufen werden, auf bestimmte Bedingungen, kannst du es so machen:
Dieser legt die Bedingungen fest, hash als Methode der Klasse (so dass es leichten Zugang), und der hash enthält lediglich den Namen der Methode zu nennen, eher als einen lambda-Ausdruck oder ähnliches. Also, wenn Sie rufen
b(0)
essend
s selbst die Nachricht enthielt in A. Bedingungen[0], diea
.InformationsquelleAutor Chuck
InformationsquelleAutor wiki
Wenn Sie wirklich wollen einfach nur ziemlich diese Art der Sache,
warum nicht wickeln Sie alle Ihre Methoden in einer Klasse etwa so:
oder, um dein Beispiel:
Einen anderen grundlegenden Fehler, die Sie gemacht ist, dass Sie initialisiert
@a
außerhalb einer Instanz-Methode -nur bare Innenseite der definition von
A
. Dies ist eine riesige no-no, weil es einfach nicht funktioniert.Denken Sie daran, in ruby ist alles ein Objekt, einschließlich der Klassen, und die
@
Präfix bedeutet, dass die Instanzvariable, jedes Objekt, ist derzeit selbst. Innerhalb einer Instanz-Methode, Definitionen,
self
ist eine Instanzvon der Klasse. Aber außerhalb der, dass, nur innerhalb der Klassendefinition
self
ist die Klasse-Objekt - so ist Sie definierteine Instanz-variable namens
@a
für die Objekt-KlasseA
, die keine Instanzen vonA
kann man direkt.Ruby hat einen Grund für dieses Verhalten (Klasse-Instanz-Variablen können praktisch, wenn Sie wirklich wissen, was
du tust), aber dies ist eine fortgeschrittene Technik.
Kurz, nur initialisieren von Instanzvariablen in der
initialize
Methode.InformationsquelleAutor rampion
Gut, die erste Zeile in deiner Klasse eine Methode aufgerufen, die nicht existiert. Es werde nicht einmal existieren, nachdem die ganze Klasse geladen wird, obwohl, da würde sich ein Aufruf der Methode der Klasse, und Sie haben nur definierte Instanz-Methoden.
Beachten Sie auch, dass {0 => a()} Aufruf der Methode a(), nicht erstellen einen Verweis auf die Methode a(). Wenn Sie wollten eine Funktion gibt, die nicht bewertet, bis später, man müsste eine Art von Lambda.
Sie könnte so etwas tun: @a = {0 => lambda{A. neue.a()}} Dann müsste man es nennen, mit @a[0].rufen
InformationsquelleAutor Phil Kulak
Ich bin ziemlich neu mit callbacks in Ruby und dies ist, wie ich erklärte es mir anhand eines Beispiels:
InformationsquelleAutor Saurabh Hirani
InformationsquelleAutor Arrow