Perl,$ | ++ 是什么意思?

3

我正在重构一些Perl代码,正如情况所示,Perl有一些奇怪的结构让人很难查找。

在这种情况下,我遇到了以下内容...

$|++;

这行代码在"use"语句之后单独成行。

这个命令是做什么用的?


4
不要使用$|++,而是使用$| = 1;。前者会给人一种误导性的印象,即增加和减少操作符可以像其他变量一样作用于$|,但是对于这个特殊变量来说并非如此。请参考http://perlmonks.org/?node_id=280025。 - DavidO
1
如果您确实需要一个“可堆叠”的效果,可以考虑使用++来实现,您可能需要考虑使用local $| = 1; - tjd
@DavidO:有趣的是,perldoc没有提到$|的“魔法”行为。从文档中是否有任何可以推断$| = 0; $| --;将把$|设置为1的内容? - Keith Thompson
如果你所说的“可堆叠”是指可以多次递增,而且在多次递减之前不会被清除,那么这就是使用++运算符与$|时产生误解的一个很好的例子。你可以将其递增100次,但它的值仍然为1。将其递减一次将使其返回0。将其递减两次将再次翻转回1。如果这对你有用,请确保在旁边加上#注释,以免让人感到惊讶。 - DavidO
@DavidO,"stackable"的意思就是像local一样,在封闭作用域结束时恢复先前的值。在100个作用域中将其设置为1,到达第100个作用域时,您会得到0回来... - tjd
显示剩余3条评论
5个回答

5

来自 perldoc perlvar:

$|

如果设置为非零值,将强制立即刷新当前选定输出通道上的每个写入或打印操作之后的缓存。默认值为0(无论系统是否真正缓存该通道;$|仅告诉您是否已要求Perl在每次写入后刷新)。如果输出到终端,则STDOUT通常是行缓冲,否则是块缓冲。当您输出到管道或套接字时(例如在rsh下运行Perl程序并希望实时查看输出时),设置此变量非常有用。这对输入缓冲没有影响,请参见getc。请参见select以了解如何选择输出通道。另请参阅IO::Handle

因此,由于始终以0开头,将其增加到1,从而在每次写入/打印后强制刷新。

您可以使用以下内容替换它,使其更加清晰易懂。

use English '-no_match_vars';
$OUTPUT_AUTOFLUSH = 1;

2
如果你使用 English一定要 使用 English '-no_match_vars',否则你将会遭受正则表达式性能惩罚(请参考 English 文档中的解释)。 - amon
感谢您添加了一个更清晰的替代方案。 - Bill

3

最好使用perlvar(perldoc perlvar或http://perldoc.perl.org/perlvar.html)来查找变量。

从中可以看出:

HANDLE->autoflush(EXPR)

$OUTPUT_AUTOFLUSH

$|

如果设置为非零值,则立即强制在当前选择的输出通道上进行刷新,以及在每次写入或打印后进行刷新。默认值为0(无论该通道是否真正由系统缓冲;$|仅告诉您是否已明确要求Perl在每次写入后进行刷新)。如果将输出发送到管道或套接字(例如在rsh下运行Perl程序并想要实时查看输出),则设置此变量会非常有用。这对输入缓冲没有影响,请参见getc。请参见select以了解如何选择输出通道。另请参见IO :: Handle。

++是自增运算符,它将一个添加到变量中。

因此,$| ++将设置autoflush为true(默认值0 + 1 = 1,布尔运算为true),这将强制stdout的写入不被缓冲。


1

$|是Perl的特殊变量之一。

根据perlvar的说明:

如果设置为非零值,则在当前选择的输出通道上立即强制执行刷新,并在每次写入或打印后执行刷新。


1
如果你只依赖Google获取信息,我能理解在Perl中查找特殊变量可能会引起困惑。幸运的是,有perldoc!每台安装了Perl的机器都应该有perldoc。不带命令行参数使用它,可以获得您的Perl版本附带的所有核心文档的列表。
  • 查找所有特殊变量:perldoc perlvar

  • 查找特定的特殊变量:perldoc -v '$|'(在*nix上,Windows上使用双引号)

  • 查找perl的函数列表:perldoc perlfunc

  • 查找特定的函数:perldoc -f sprintf

  • 查找运算符(包括优先级):perldoc perlop

掌握这些信息后,您就会知道当您对输出自动刷新变量进行后增量操作时会发生什么。

作为一个特别的奖励,perldoc.perl.org 可以处理所有这些工作,除了 -v 搜索...

1
正如其他人所指出的那样,它可以在所选输出文件句柄(可能是 STDOUT)上启用自动刷新。但是,没有人说过,在你通常重构和整理代码的同时,你真的应该将其替换为等效但更明显的内容。
STDOUT->autoflush(1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接