Betrachten Sie den folgenden Perl-Code.
%Vor% Das Skript gibt offensichtlich 1
aus. Ich hätte gerne, was auch immer der aktuelle Wert von $b
ist.
Was wäre der schlaueste Weg in Perl, um eine solche faule Bewertung zu erreichen? Ich möchte, dass das ${b}
"nicht ersetzt" bleibt, bis $a
benötigt wird.
Ich bin mehr daran interessiert zu wissen, warum Sie das tun wollen. Je nachdem, was Sie wirklich tun müssen, können Sie verschiedene Vorgehensweisen verwenden.
Sie könnten den Code in eine Coderef einbinden und nur dann auswerten, wenn Sie sie benötigen:
%Vor%Eine Variante wäre, eine benannte Funktion als closure (Dies ist wahrscheinlich der beste Ansatz, im größeren Kontext Ihres Aufrufcodes):
%Vor%Sie können eine Referenz auf die ursprüngliche Variable verwenden und sie bei Bedarf dereferenzieren:
%Vor%Perl interpoliert eine Zeichenkette, wenn der Code läuft, und ich weiß nicht, wie ich das machen könnte, wenn ich nicht über Formate verfüge (die hässlich sind). Was Sie jedoch tun könnten, ist die Änderung "wenn der Code ausgeführt wird" zu etwas bequemerem, indem Sie die Zeichenfolge in eine Unterstruktur einfügen und sie aufrufen, wenn Sie die interpolierte Zeichenfolge benötigen ...
%Vor%Oder du könntest Eval-Magie einsetzen, aber es ist etwas aufdringlicher (du musst die Saite manipulieren, um es zu erreichen).
Was Sie wollen, ist keine faule Auswertung, sondern späte Bindung . Um es in Perl zu erhalten, müssen Sie eval
verwenden.
Bitte beachten Sie, dass eval
normalerweise sowohl ineffizient als auch methodisch scheußlich ist. Sie sind fast sicher besser dran, eine Lösung aus einer der anderen Antworten zu verwenden.
Wie andere bereits erwähnt haben, wertet Perl Zeichenfolgen nur aus, wenn Sie sie mit eval
geschrieben haben, um den Compiler zur Laufzeit aufzurufen. Sie könnten Referenzen verwenden, wie in einigen anderen Antworten erwähnt, aber das ändert die Art, wie der Code aussieht ( $$a
vs $a
). Da es sich jedoch um Perl handelt, können Sie erweiterte Funktionen hinter einer einfachen Variablen verbergen, indem Sie tie
verwenden.
Sie können die Dokumentation für tie
nachschlagen, aber kurz gesagt können Sie damit Ihre eigene Implementierung einer Variablen (für Skalare, Arrays, Hashes oder Dateihandles) definieren. Dieser Code erstellt also die neue Variable $a
mit einer Implementierung, die den aktuellen Wert von $b
erhält oder setzt (indem intern ein Verweis auf $b
gespeichert wird). Die Methode new
wird nicht unbedingt benötigt (der Konstruktor ist tatsächlich TIESCALAR
), wird aber als syntaktischer Zucker bereitgestellt, um tie
nicht direkt im aufrufenden Code verwenden zu müssen.
(was wäre tie my $a, 'Lazy', $b;
)
Sie möchten vorgeben, dass sich $ a auf etwas bezieht, das ausgewertet wird, wenn $ a verwendet wird ... Sie können das nur tun, wenn $ a nicht wirklich ein Skalar ist, könnte es eine Funktion sein (wie cHaos Antwort) oder In diesem einfachen Fall eine Referenz auf die andere Variable
%Vor%Ich möchte, dass das $ {b} "nicht ersetzbar" bleibt, bis $ a benötigt wird.
Dann würde ich empfehlen, die String-Interpolation zu vermeiden, stattdessen sprintf
, damit Sie "interpolieren". wenn nötig.
Natürlich könntest du auf dieser Grundlage tie
zusammen etwas schnell (ish) und schmutzig machen:
Funktioniert auch mit exotischen Formatangaben. Yuck.
Tags und Links string perl lazy-evaluation