如何告诉perl打印到文件句柄而不是打印文件句柄?

lxg*_*xgr 12 perl

我试图绕过Perl处理参数解析的方式print.

为什么这样呢

print $fh $stufftowrite
Run Code Online (Sandbox Code Playgroud)

按预期写入文件句柄,但是

print($fh, $stufftowrite)
Run Code Online (Sandbox Code Playgroud)

文件句柄STDOUT代替?

我的猜测是它与文档中的警告有关print:

注意不要使用左括号跟随print关键字,除非您希望相应的右括号终止print的参数; 将括号括在所有参数周围(或插入一个+,但看起来不那么好).

我是否应该习惯第一种形式(这对我来说似乎不对,来自于所有使用围绕函数参数的括号的语言),还是有办法告诉Perl做我想做的事情?

到目前为止,我已经在第一个,第二个和两个参数周围尝试了很多括号组合,但没有成功.

amo*_*mon 18

在列表上

该结构bareword (LIST1), LIST2意味着"将函数bareword应用于参数LIST1",虽然bareword +(LIST1), LIST2可以,但不一定意味着"应用于bareword组合列表的参数LIST1, LIST2".这对于分组参数很重要:

my ($a, $b, $c) = (0..2);
print ($a or $b), $c;  # print $b
print +($a or $b), $c; # print $b, $c
Run Code Online (Sandbox Code Playgroud)

前缀+也可以用来区分hashrefs和块,以及函数来自barewords,例如,当订阅hash时:$hash{shift}返回shift元素,同时$hash{+shift}调用函数shift并返回值的hash元素shift.

间接语法

在面向对象的Perl中,通常使用箭头语法调用对象上的方法:

$object->method(LIST);   # call `method` on `$object` with args `LIST`.
Run Code Online (Sandbox Code Playgroud)

但是,有可能(但建议)使用将动词放在第一位的间接表示法:

method $object (LIST);   # the same, but stupid.
Run Code Online (Sandbox Code Playgroud)

因为类只是它们自身的实例(在语法意义上),所以你也可以调用它们的方法.这就是为什么

new Class (ARGS);  # bad style, but pretty
Run Code Online (Sandbox Code Playgroud)

是相同的

Class->new(ARGS);  # good style, but ugly
Run Code Online (Sandbox Code Playgroud)

但是,这有时会使解析器混淆,因此不建议使用间接样式.

但它确实暗示了印刷品的作用:

print $fh ARGS
Run Code Online (Sandbox Code Playgroud)

是相同的

$fh->print(ARGS)
Run Code Online (Sandbox Code Playgroud)

实际上,文件句柄$fh被视为类的对象IO::Handle.

(虽然这是一个有效的句法解释,但它并不完全正确.IO::Handle它本身的来源使用了这条线print $this @_;.打印函数就是这样定义的.)


TLP*_*TLP 14

看起来你有一个错字.您在第二个print语句中的文件句柄和参数之间放了一个逗号.如果这样做,文件句柄将被视为参数.这似乎只适用于词法文件句柄.如果使用全局文件句柄,它将产生致命错误

No comma allowed after filehandle at ...
Run Code Online (Sandbox Code Playgroud)

所以,要明确的是,如果你必须为你print做括号,请执行以下操作:

print($fh $stufftowrite)
Run Code Online (Sandbox Code Playgroud)

虽然我个人更喜欢不使用括号,除非我必须这样做,因为它们只是增加了混乱.


cre*_*ive 9

现代Perl书在第11章("要避免什么"),"间接符号标量限制"一节中说明:

语法的另一个危险是解析器期望单个标量表达式作为对象.打印到存储在聚合变量中的文件句柄似乎很明显,但它不是:

# DOES NOT WORK AS WRITTEN
say $config->{output} 'Fun diagnostic message!';
Run Code Online (Sandbox Code Playgroud)

Perl将尝试在$ config对象上调用say. print,closesay- 所有以文件句柄操作的内置函数 - 以间接方式操作.当文件句柄是包全局变量时,这很好,但词法文件句柄(Filehandle References)使间接对象语法问题变得明显.要解决此问题,请消除产生预期调用的子表达式的歧义:

say {$config->{output}} 'Fun diagnostic message!';
Run Code Online (Sandbox Code Playgroud)

当然,print({$fh} $stufftowrite)也有可能.