20

最近我遇到了这种过滤列表的每一秒值的方法:

perl -E 'say grep --$|, 1..10'
13579

它是如何工作的?

4

4 回答 4

25

$|是一个特殊的 Perl 变量,它的值只能是 0 和 1。任何真正的非零值的赋值,$|比如

$| = 1;
$| ='富';
$| = "4asdf"; # 0 + "4asdf" 是 4
$| = \@a;

将具有设置$|为 1 的效果。任何分配的零值

$| = 0;
$| = "";
$| = 未定义;
$| =“呃”;# 0 + "erk" 为 0

将设置$|为 0。

展开--$|$| = $| - 1,现在您可以看到发生了什么。如果$|原本为 1,则将--$|值更改为 0。如果$|原本为 0,--$|则将尝试将值设置为 -1,但实际上会将值设置为 1。

于 2011-02-10T15:48:45.557 回答
6

哈! $|当“预先递减”时,在零(假,在 perl 中)和一(真)的值之间翻转——它只能保存这些值。

因此,您的grep标准在每次通过时都会发生变化,变为真、假、真、假等,因此返回列表中的所有其他元素。

太聪明了一半。

于 2011-02-10T15:50:48.183 回答
3

$|只能是零或一。默认值为0,因此通过在第 0 个索引之前将其递减grep,它将为 1。

随后的递减实际上会将其从零“切换”到一再到零等等。

于 2011-02-10T15:50:31.997 回答
3

关键是这种用法只是一个讨厌的黑客。
$|(或他更易读的别名$OUTPUT_AUTOFLUSH)是一个特殊的变量来控制STDOUT(或当前选定的文件句柄)的自动刷新。因此它只接受真(1)或假(0)。

于 2011-02-10T20:58:38.410 回答