Perl 是否有规则告诉我必须选择什么形式的STDOUT/STDERR/SDTIN?

Perl 是否有规则告诉我必须选择什么形式的STDOUT/STDERR/SDTIN?,perl,stdout,stdin,stderr,Perl,Stdout,Stdin,Stderr,有时我不得不使用空字“STDOUT”,有时空字不起作用,有时我可以使用空字或其他形式。有没有规则告诉我什么时候我必须选择表格,什么时候我可以选择其他表格 #!/usr/bin/env perl use warnings; use 5.12.0; use utf8; print STDOUT "Something\n"; # works print \*STDOUT "Something\n"; # String found where opera

有时我不得不使用空字“STDOUT”,有时空字不起作用,有时我可以使用空字或其他形式。有没有规则告诉我什么时候我必须选择表格,什么时候我可以选择其他表格

#!/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 

根据我的测试,以下是规则:

  • use strict subs
    生效时,裸字版本不能作为文件句柄传递,可能是因为它们可能是子例程调用

  • *STDOUT
    \*STDOUT
    版本可随时用于传递给函数

  • 通过
    foo STDOUT
    (不带括号)将其中一个传递给sub会中断,因为perl假定这是
    STDOUT->foo

  • 除了案例1和案例3之外,您还可以通过bareword Verison将它们传递给SUB

  • 对于调用
    print
    printf
    等,必须使用纯文字版本,或使用
    {}
    。将文件句柄封装在
    {}
    中告诉perl第一个参数是文件句柄,因此可以使用任何形式

  • 出于这些目的,
    -t
    与接受文件句柄的其他
    -X
    测试一样,也算作子测试

    当您将
    {}
    print
    printf
    一起使用时,
    {}
    内的部分是一个代码块;将对其求值,并将结果用作文件句柄。它与这些函数一起工作,因为perl对它们进行了特殊处理,处理方式与
    map
    grep
    相同

    所以,遵循这些规则,你会没事的:

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

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

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

    我早在perl 5.8.7中就进行了测试。这是我现在能走的最远的地方了。上述内容也适用于5.6。

    如何
    print{\*STDOUT}“Something\n”(作者声明它是有效的)而您的第五条规则perldoc.perl.org说FILEHANDLE可能是一个标量变量,包含FILEHANDLE的名称或对FILEHANDLE的引用,因此引入了一个间接级别。对于
    打印
    。最后还描述了块情况。