Ich rufe eine Methode mit einem Block auf;
%Vor%und die Methode ist definiert als;
%Vor%und beim Definieren der Methode ; Ich möchte überprüfen, ob der angegebene Block leer ist (nil) oder nicht, weil die Variable in der Methode so enden kann;
%Vor%Also in Definition, ich möchte überprüfen, ob der ertrag Block ist Null oder nicht. Wie;
%Vor%Ich weiß, dass das obige nicht funktioniert. Bu, das will ich erreichen.
Denken Sie auch daran, dass block_given? immer "true" ist, da der Block auch dann gegeben ist, wenn er nil oder leere Zeichenfolge ist .
UPDATE : Wie die meisten Kommentare / Antworten sagen, ist die Frage unklar; Hier ist das Problem von @ndn vereinfacht:
Ich möchte prüfen, ob das Ergebnis der Ausführung eines Blocks "leer" (nil oder "") ohne ist Rufen Sie es zuerst auf.
Es ist unklar, was Sie fragen, weil ein Block selbst nicht leer sein kann. Daher könnten Sie ein paar verschiedene Dinge meinen:
Ein fehlender Block. Sie können prüfen, ob ein Block gegeben ist
%Vor%{}
oder do end
). Dies ist nicht unmöglich, erfordert aber fortgeschrittene Voodoo-Rubin-Metaprogrammierungs-Magie. Im Allgemeinen, wenn Sie das suchen, schreiben Sie entweder etwas sehr Interessantes oder Ihr Ansatz ist völlig falsch. Sie möchten prüfen, ob das Ergebnis der Ausführung eines Blocks "leer" ist, ohne es zuvor aufzurufen. Das ist unmöglich. Betrachten Sie beispielsweise den folgenden Block:
%Vor%Offensichtlich gibt es keine Möglichkeit, im Voraus zu wissen.
Sie können den Block aufrufen. Dann können Sie das Ergebnis einer Variablen zuweisen und prüfen:
%Vor% Wenn Sie nun some_method
aufrufen:
BEARBEITEN : Eine Problemumgehung für Fall Nr. 3 besteht möglicherweise darin, zwei Prozeduren zu erstellen, einen mit dem, was Sie tun möchten, wenn der Block "leer" ist, und einen - falls nicht, dann übergeben Sie ihn an den Endpunkt, an dem Sie den Block schließlich aufrufen. Dies kann oder kann nicht anwendbar sein, abhängig von Ihrer genauen Situation.
EDIT2 :
Eine andere Problemumgehung kann sein, die Methode Proc#call
für Ihre Proc-Instanzen neu zu definieren. Dies funktioniert jedoch nicht für yield
:
EDIT3 : Eine andere Alternative, die eine Art von Betrug ist, besteht darin, den gegebenen proc in einen anderen proc zu verpacken. Auf diese Weise funktioniert es auch für yield
.
Wenn Sie nun das Ergebnis von wrap
verwenden, erhalten Sie ein ähnliches Verhalten wie secure
.
Wenn ich es richtig verstehe, wollen Sie statisch feststellen, was der Laufzeitwert eines Blocks ist. Dies ist eines der vielen unmöglichen Probleme, die sich aus der Unentscheidbarkeit des Halteproblems ergeben.
Mit anderen Worten: Es kann nicht gemacht werden.
Nicht "es kann nicht in Ruby gemacht werden", nicht "es ist schwer", es kann einfach nicht gemacht werden, Punkt. Und es kann (und wurde) mathematisch bewiesen werden, dass es nicht möglich ist. Immer.
AKTUALISIERTE Antwort Mein letzter Versuch , um die Antwort basierend auf Kommentaren zu vereinfachen.
Sie können mit block_given?
auf Blockleerheit prüfen und Sie müssen explizit auf yield
output für Leere wie unten
Ausgabe des Programms
%Vor%