Thomas Hofmann: qq und Dateien

Hallo,

ich möchte folgendes machen:

In einer Textdatei steht:
Ich heiße $Name und bin $Alter Jahre alt.

Im Programm habe Initialisiere ich die Variablen $Name und $Alter, lesen die Datei ein und gebe Sie aus, wobei eine Interpretation der Variablen erfolgen soll.

Das habe ich mir folgendermaßen gedacht:

$FileName="text.txt";
$READ="<";
$READFILE=$READ.$FileName;

$ERR_FILEOPEN="<H1>Fehler beim Öffnen der Datei".$FileName." !<BR>Wahrscheinlich wird die Datei gerade aktualisiert.</H1>";

$Name="Thomas Hofmann";
$Alter="31";
open(TEMPLATE,$READFILE);
$Template=<TEMPLATE>;
close TEMPLATE;
print qq($Template);

Das geht so aber nicht; die Variablen werden nicht interpretiert. Ich habe jedoch soetwas irgendwo mal gelesen, weiß aber nicht mehr wo.

Hat einer von Euch Cracks eine Ahnung wie es richtig geht?

Gruß und Dank
Thomas

  1. Hallo Thomas;

    In einer Textdatei steht:
    Ich heiße $Name und bin $Alter Jahre alt.

    Im Programm habe Initialisiere ich die Variablen $Name und $Alter, lesen die Datei ein und
    $Name="Thomas Hofmann";
    $Alter="31";
    open(TEMPLATE,$READFILE);
    $Template=<TEMPLATE>;
    close TEMPLATE;
    print qq($Template);

    So funktioniert es:

    bevor Du die letzte Ausgabe schreibst noch:

    $Template =~ s/$Name/$Name/;
    $Template =~ s/$Alter/$Alter/;

    danach

    print qq($Template);

    Viele Gruesse

    Beate Mielke

  2. Auch hallo!

    print qq($Template);

    Damit hast Du nichts anderes geschrieben als
        print "$Template";
    Jetzt klar, dass es nicht klappt? (<37555.html>, http://www.activeState.com/ActivePerl/docs/lib/Pod/perlop.html#Quote_and_Quote_like_Operators)

    Entweder Du machst es so, wie Beate es gezeigt hat, oder Du benutzt eval(), das es in den meisten Scriptsprachen fuer solche Zwecke gibt:
        print eval($Template);
    (http://www.activeState.com/ActivePerl/docs/lib/Pod/perlfunc.html#item_eval)

    Calocybe

    1. Hallo Calocybe,

      ..., oder Du benutzt eval(), das es in den meisten Scriptsprachen fuer solche Zwecke gibt:
          print eval($Template);

      Theoretisch muesste es tatsaechlich so funktionieren. Ich hatte das auch so getestet. Fuehrt aber zu der Fehlermeldung, dass die beiden Variablen $Alter und $Name nur einmal definiert werden und spaeter nicht mehr verwendet werden. Das muss daher kommen, dass Perl die beiden Variablen irgendwie anders behandelt, weil sie aus der Dateizeile kommen.

      Jedenfalls fuehrt

      print eval($Template);

      dadurch zu einer Fehlermeldung und wird nicht interpretiert.

      Viele Gruesse

      Beate Mielke

      1. Hi!

        Nach langem Rumprobieren bin ich nun endlich drauf gekommen, was falsch ist.

        Theoretisch muesste es tatsaechlich so funktionieren. Ich hatte das auch so getestet. Fuehrt aber zu der Fehlermeldung, dass die beiden Variablen $Alter und $Name nur einmal definiert werden und spaeter nicht mehr verwendet werden. Das muss daher kommen, dass Perl die beiden Variablen irgendwie anders behandelt, weil sie aus der Dateizeile kommen.

        Das sind Warnungen, die von Perl (mit Option -w) nach der Kompilirung erzeugt werden. Perl kann zu diesem Zeitpunkt nicht wissen, dass ich die Variablen innerhalb eines eval() eben doch noch mal verwenden werde.

        Jedenfalls fuehrt
        print eval($Template);
        dadurch zu einer Fehlermeldung und wird nicht interpretiert.

        Ja, mir ist inzwischen auch klar, warum. Denn das ist ja gleichbedeutend mit
            print eval('Ich heisse $Name und bin $Alter Jahre alt.');
        bzw. dasselbe, wie wenn ich mitten im Perlcode einfach
            Ich heisse $Name und bin $Alter Jahre alt.
        schreiben wuerde. Sehe ich ein, dass es so nicht gehen kann. ;-)

        Wuerde man
            print eval('$Template');
        schreiben, wuerde $Template erst vom eval selbst aufgeloest werden, die Ausgabe ist dann also
            Ich heisse $Name und bin $Alter Jahre alt.
        .

        Schreibt man
            print eval("$Template");
        ist das dasselbe, wie mein erster Vorschlag, da die Variable innerhalb der "" aufgeloest wird.

        Und wie erreichen wir nun unser Ziel, wenn wir beim eval bleiben wollen (eval hat gegenueber Deinem Vorschlag den Vorteil, dass man die Variablennamen im Template vorher nicht kennen muss)? eval muss einen String bekommen, der mit " anfaengt und aufhoert (d.h. das erste und letzte Zeichen des String selbst sind Anfuehrungszeichen), und zwischendrin befindet sich das bereits aufgeloeste $Template, sodass eval dan $Name und $Alter aufloesen kann.
            print eval('"' . $Template . '"');
        sollte klappen.

        Calocybe

        1. Hallo Calocybe,

          ...eval hat gegenueber Deinem Vorschlag den Vorteil, dass man die Variablennamen im Template vorher nicht kennen muss

          Stimmt, waere auf jeden Fall die elegantere Loesung.

          eval muss einen String bekommen, der mit " anfaengt und aufhoert (d.h. das erste und letzte Zeichen des String selbst sind Anfuehrungszeichen), und zwischendrin befindet sich das bereits aufgeloeste $Template, sodass eval dan $Name und $Alter aufloesen kann.

          print eval('"' . $Template . '"'); sollte klappen.

          Und es funktioniert tatsaechlich.
          Man muss zwar erstmal um drei Ecken denken, um das zu verstehen, aber irgendwann leuchtet's so laaaaangsaaaam ein.

          Genial !

          Viele Gruesse

          Beate Mielke