是否有规则告诉我必须选择哪种形式的 STDOUT/STDERR/SDTIN



有时我不得不使用裸词"STDOUT",有时裸词不起作用,有时我可以使用裸词或其他形式。是否有规则告诉我何时必须在表格上选择,何时可以选择另一种形式,以及何时可以选择表格?

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

print STDOUT "Somethingn";             # works
print *STDOUT "Somethingn";           # String found where operator expected 
print { STDOUT } "Somethingn";         # Bareword "STDOUT" not allowed while "strict subs" in use 
print { *STDOUT } "Somethingn"        # 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 

根据我的测试,这些是规则:

  1. use strict subs生效时,裸词版本不能作为文件句柄传递,大概是因为它们可能是子例程调用。

  2. *STDOUT*STDOUT 版本可用于始终传递给函数。

  3. 将其中一个传递给带有 foo STDOUT(不带括号(中断的 sub,因为 Perl 假设这是STDOUT->foo

  4. 除了情况 1 和 3 之外,您还可以将它们传递给带有裸词版本的子。

  5. 对于printprintf等的调用,您必须使用裸词版本或使用 {} 。 将文件句柄包含在{}告诉Perl是的,第一个参数是文件句柄,所以你可以使用任何形式。

出于这些目的,-t算作 sub,其他接受文件句柄的-X测试也是如此。

当您将{}printprintf一起使用时,{} 中的部分是一个代码块;它被计算并将结果用作文件句柄。 它适用于这些函数,因为它们被 perl 以与 mapgrep 相同的方式处理。

因此,请遵循以下规则,您将没事的:

  • 明确打印到 STDERR 或 STDOUT 时,请使用裸词版本:

    print STDERR "ERRORRRRRn";
    
  • 以任何其他方式使用文件句柄时,请使用*版本:

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

我测试了 perl 5.8.7。 这是我现在能说的。 以上应该也适用于 5.6。

最新更新