我见过一些用 Perl 编写的可怕代码,但我无法理解这个代码:
select((select(s),$|=1)[0])
它在我们用来与服务器通信的一些网络代码中,我认为它与缓冲有关(因为它设置了$|
)。
但我无法弄清楚为什么会有多个select
调用或数组引用。谁能帮我吗?
在 STDOUT 以外的文件句柄上设置 autoflush 是一个讨厌的小习惯。
select()
获取提供的文件句柄并(基本上)用它替换 STDOUT,并在完成后返回旧的文件句柄。
所以(select($s),$|=1)
重定向文件句柄(记住select
返回旧的),并设置自动刷新($| = 1
)。它在列表 ( (...)[0]
) 中执行此操作并返回第一个值(这是select
调用的结果 - 原始 STDOUT),然后将其传递回另一个select
以恢复原始 STDOUT 文件句柄。呸。
但现在你明白了(好吧,也许;)),改为这样做:
use IO::Handle;
$fh->autoflush;
找出任何代码的方法是将其分开。你知道括号内的东西在外面的东西之前发生。这与您弄清楚其他语言中的代码在做什么的方式相同。
那么第一位是:
( select(s), $|=1 )
该列表有两个元素,它们是两个操作的结果:一个选择s
文件句柄作为默认值,然后一个设置$|
为真值。这$|
是每个文件句柄变量之一,仅适用于当前选定的文件句柄(请参阅The Effective Perler中的了解全局变量)。最后,您有一个包含两项的列表:先前的默认文件句柄(的结果)和 1。select
下一部分是一个文字列表切片,用于提取索引 0 中的项目:
( PREVIOUS_DEFAULT, 1 )[0]
其结果是作为先前默认文件句柄的单个项目。
下一部分获取切片的结果并将其用作另一个调用的参数select
select( PREVIOUS_DEFAULT );
因此,实际上,您已经设置$|
了文件句柄并最终回到了使用默认文件句柄开始的位置。
select($fh)
选择一个新的默认文件句柄。请参阅http://perldoc.perl.org/functions/select.html
(select($fh), $|=1)
打开自动冲洗。请参阅http://perldoc.perl.org/perlvar.html
(select($fh), $|=1)[0]
返回此元组的第一个值。
select((select($fh), $|=1)[0])
select
它,即恢复旧的默认文件句柄。
相当于
$oldfh = select($fh);
$| = 1;
select($oldfh);
意思是
use IO::Handle;
$fh->autoflush(1);
如 perldoc 页面所示。
在另一个场合,我曾经提出一个更易于理解的版本是这样的:
for ( select $fh ) { $| = 1; select $_ }
这保留了紧凑习语的唯一优势,即不需要在周围范围内声明变量。
或者如果你不习惯$_
,你可以这样写:
for my $prevfh ( select $fh ) { $| = 1; select $prevfh }
的范围$prevfh
仅限于for
块。(但如果你编写 Perl,你真的没有理由对 . 感到不安$_
。)
在句柄上打开缓冲区刷新s
然后重新选择当前句柄是非常聪明的代码。
查看perldoc -f select
更多。
请检查perldoc -f select。的含义$|
,请查看perldoc perlvar
跳过加载 IO::Handle 是过度优化。
use IO::Handle;
$fh->autoflush(1);
更具可读性。