Perl, String langsam auswerten

7

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.

    
Mike 03.06.2010, 17:58
quelle

6 Antworten

15

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%     
Ether 03.06.2010, 18:27
quelle
4

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).

    
cHao 03.06.2010 18:08
quelle
3

Was Sie wollen, ist keine faule Auswertung, sondern späte Bindung . Um es in Perl zu erhalten, müssen Sie eval verwenden.

%Vor%

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.

    
Kilian Foth 03.06.2010 19:04
quelle
3

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.

%Vor%

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; )

    
Eric Strom 03.06.2010 21:47
quelle
1

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%     
leonbloy 03.06.2010 18:27
quelle
1
  

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:

%Vor%

Funktioniert auch mit exotischen Formatangaben. Yuck.

    
pilcrow 10.06.2010 06:10
quelle

Tags und Links