2009-06-15 10 views
1

Ok, ich habe ein bisschen ein Problem hier. Ich merke, dass ich kein $ Handle auf * :: HTML setzen muss, um diesen Code-Schnipsel zum Laufen zu bringen, allerdings wird dieser Code aus seinem Kontext herausgenommen und ich brauche ihn tatsächlich, um mit $ handle zu arbeiten. Die Ausgabe, die ich erhalte, ist unterhalb des Snippets, aber die Ausgabe, die ich möchte, ist für die Datei.html, die "what \ nsometext1 \ nsometext2 \ n" enthält.Perl Glob und Dateihandle Probleme

open(HTML, ">file.html"); 
$handle = \*::HTML; 
print $handle "what\n"; 

open(READ, "< somefile.txt"); #somefile.txt contains sometext1\nsometext2\n 
while(<READ>) 
{ 
    print $handle; 
} 
close READ; 
close HTML; 

file.html mit dem Ausgang "was" und glob (0x6278b0) glob (0x6278b0) bleibt, ist an der Klemme Fenster gedruckt.

Antwort

11

Wenn Sie die documentation for print sehen Sie werden sehen, dass es drei gültige Möglichkeiten print zu nennen:

  • Druckfilehandle LIST
  • Druckliste
  • Druck

Nur die letzte Version druckt $_ implizit. Der Grund dafür ist einfach, Perl kann nicht sagen, ob Sie das Dateihandle oder das Dateihandle ohne weitere Informationen drucken möchten (das Leerzeichen zwischen Dateihandle und Liste). Das Drucken des Dateihandles (statt dessen) ist die flexibelste Methode, daher wurde die Auflösung des mehrdeutigen Falls gewählt.

+2

Tatsächlich verwendet "print HANDLE" auch $ _, aber Perl analysiert stattdessen einen mehrdeutigen Skalar als "print LIST". (Und "print {$ fh}" ist ein Syntaxfehler.) –

1

Ich fand es heraus; Ich brauche dafür die $_ nach $handle.

+0

Drucken ist kontextsensitiv - mit einem einzigen Argument wird davon ausgegangen, dass Sie auf STDOUT drucken möchten; Bei zwei oder mehr Argumenten muss der erste der Glob sein, auf dem gedruckt werden soll. Und weil Sie bereits ein Argument zum Drucken angegeben haben, $ handle, wird $ _ nicht als Standardargument verwendet. –

4

Wenn Sie skalare Variablen verwenden, um Dateihandles zu speichern, müssen Sie Perl helfen, zu verstehen, wie der Ausdruck analysiert wird. Das Sagen print $var ist mehrdeutig. Es könnte einen der folgenden Punkte bedeuten:

print STDOUT $var; # print the contents of $var to STDOUT 
print {$var} $_; # print the contents of $_ to the handle $var 

Perl wählt den ersten. Wenn Sie das letztere möchten, müssen Sie es explizit machen, indem Sie das Dateihandle einklammern, um es zu disambiguieren.

Außerdem verwendet Perl nur die Standardvariable $_, wenn Sie keine Argumente angeben, was gedruckt werden soll. Aufgrund dessen, wie print $var interpretiert wird, wird $_ nicht verwendet.

3

Perls print operator lässt in allen Fällen LIST weglassen. Bedenken Sie:

$ perl -le '$_ = "foo!"; print STDOUT' 
foo! 

Aber das sieht an den Parser wie ein Dateihandle-im Gegensatz zu print $scalar, die etwas zur Laufzeit sein könnte. Wenn Sie ein Stück Code unsicher des Parse sind, führen Sie es durch B::Deparse, wie in

$ perl -MO=Deparse,-p try 
while (defined(($_ = <READ>))) { 
    print($_); 
    print($handle); 
    print(STDOUT $_); 
} 

Wie geschrieben, enthält die Schleife drei Anrufe Druck: print, print $handle und print STDOUT.

nahe zu kommen, was Sie wollen, können Sie select verwenden:

my $oldfh = select $handle; 

while(<READ>) 
{ 
    print; 
} 

select $oldfh; 

Beachten Sie, dass kehrt die zuvor ausgewählte Dateikennung aus, und der Code speichert es oben so wie die Dinge zurück zu setzen, wo wir sie gefunden nachher.

1
use strict; 
use warnings; 

open(my $html, '>', "file.html"); 
print $html "what\n"; 

open(my $read, '<', "somefile.txt"); #somefile.txt contains sometext1\nsometext2\n 

while(my $line = <$read>) { 
    print {$handle} $line; 
} 

close $read; 
close $html; 
Verwandte Themen