2009-06-15 88 views
1

好的,我在這裏有一些問題。我意識到我不需要爲*:HTML設置一個$ handle來獲得這個片段的工作,但是這段代碼從它的使用中脫離了上下文,事實上我需要這個來處理$ handle。我收到的輸出在片段之下,但是我想要的輸出是file.html包含「what \ nsometext1 \ nsometext2 \ n」。Perl glob和文件句柄問題

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留下與輸出 「什麼」 和GLOB(0x6278b0)GLOB(0x6278b0)被打印到終端窗口。

回答

11

如果你看一下documentation for print,你會看到有三個有效的方法來調用print

  • 打印FILEHANDLE LIST
  • 打印列表
  • 打印

只有最後版本隱含地打印$_。原因很簡單,Perl無法確定是否打印文件句柄或沒有更多信息(文件句柄和列表之間的空白)而打印文件句柄。打印文件句柄(而不是文件句柄)是最靈活的方法,因此他們選擇了模糊情況的解決方案。

+2

實際上,「print HANDLE」也使用$ _,但是perl卻將一個模糊的標量解析爲「print LIST」。 (並且「print {$ fh}」是一個語法錯誤。) – 2009-06-15 17:24:07

1

我想通了;爲此,我需要之後的$_

+0

打印是上下文敏感的 - 只有一個參數,它假定你想打印到STDOUT;有兩個或更多的參數,它需要第一個是你想要打印的glob。而且由於你指定了一個參數來打印已經是$ handle,它不會使用$ _作爲默認參數。 – 2009-06-15 17:09:34

4

當你使用標量變量來保存文件句柄時,你必須幫助Perl理解如何解析表達式。說print $var是不明確的。這可能意味着以下兩種情況之一:

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

Perl挑選前者。如果你想要後者,你需要通過包圍文件句柄來明確它。

此外,當您不提供任何打印內容的參數時,Perl僅使用默認變量$_。由於如何解釋print $var,因此不使用$_

3

Perl的print operator的確在所有情況下都允許省略LIST。試想一下:

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

但是這看起來解析器像文件句柄不像print $scalar,這可能是在運行任何東西。如果你不確定解析了一些代碼的,餵它通過B::Deparse,如

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

書面,循環包含三個調用打印:printprint $handleprint STDOUT

要親近你想要什麼,你可能會使用select

my $oldfh = select $handle; 

while(<READ>) 
{ 
    print; 
} 

select $oldfh; 

注意選擇返回先前所選的文件句柄,和上面的代碼將其保存,以便把東西放回原處,我們發現他們之後。

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;