2012-05-07 44 views
9

有時候我不得不使用裸詞「STDOUT」,有時光劍不起作用,有時我可以使用裸詞或其他形式。是否有規則,告訴我什麼時候必須在表格上選擇,何時以及何時可以選擇表格?是否有規則告訴我必須選擇哪種形式的STDOUT/STDERR/SDTIN?

#!/usr/bin/env perl 
use warnings; 
use 5.12.0; 
use utf8; 


print STDOUT "Something\n";    # works 

print \*STDOUT "Something\n";   # String found where operator expected 

print { STDOUT } "Something\n";   # Bareword "STDOUT" not allowed while "strict subs" in use 

print { \*STDOUT } "Something\n"  # works 


my $fh; 

$fh = -t STDOUT ? STDOUT : STDERR;  # Bareword "STDOUT"/"STDERR" not allowed while "strict subs" in use 

$fh = -t STDOUT ? \*STDOUT : \*STDERR; # works 

$fh = -t \*STDOUT ? \*STDOUT : \*STDERR; # works 

回答

12

這些根據我的測試規則:

  1. use strict subs生效,該裸字的版本不能作爲文件句柄傳遞,大概是因爲他們可能是子程序調用。

  2. *STDOUT\*STDOUT版本可以一直用於傳遞函數。

  3. 將其中一個傳遞給foo STDOUT(無括號)的子文件中斷,因爲perl假定爲STDOUT->foo

  4. 除了案例1和案例3,您還可以將它們傳遞給子公司,並使用裸詞verisons。

  5. 撥打電話print,printf等,您必須使用裸字版本,或使用{}。在{}中包含文件句柄告訴perl,第一個參數是一個文件句柄,所以你可以使用任何形式。

爲了這些目的-t算作子,如做其他-X測試,接受文件句柄。

當您使用{}printprintf時,{}中的部分是一個代碼塊;它被評估並且結果被用作文件句柄。它適用於這些功能,因爲它們被perl專門處理,與mapgrep相同。

所以遵循這些規則,你會好起來的:

  • 打印到STDERR或STDOUT explcitly時,使用裸字版:

    print STDERR "ERRORRRRR\n"; 
    
  • 以任何其他方式使用文件句柄時,使用*版本:

    my $isterm = -t *STDOUT; 
    close(*STDERR); 
    

我測試了早在perl 5.8.7。這可以追溯到現在我可以走了。以上應爲也適用於5.6。

+0

怎麼樣'print {\ * STDOUT}「Something \ n」;'(作者說它有效)和你的第5條規則? – ArtM

+0

非常正確。讓我檢查*爲什麼*有效。 –

+0

perldoc.perl.org表示* FILEHANDLE可能是一個標量變量,它包含文件句柄的名稱或引用,因此引入了一個間接級別*,用於'print'。最後還描述了* block *的情況。 – ArtM

相關問題