在Perl中“select((select(s),$ | = 1)[0])”做什么?

时间:2008-10-13 05:00:54

标签: perl select buffering

我见过用Perl编写的一些可怕的代码,但是我不能做出这个代码的头部和尾部:

select((select(s),$|=1)[0])

我们使用一些网络代码与服务器进行通信,我认为它与缓冲有关(因为它设置了$|)。

但我无法弄清楚为什么会有多个select调用或数组引用。任何人都可以帮助我吗?

7 个答案:

答案 0 :(得分:63)

在STDOUT以外的文件句柄上设置autoflush是一个讨厌的小习惯用法。

select()获取提供的文件句柄并(基本上)用它替换STDOUT,并在完成后返回旧的文件句柄。

因此(select($s),$|=1)重定向文件句柄(请记住select返回旧文件句柄),并设置autoflush($| = 1)。它在列表((...)[0])中执行此操作并返回第一个值(这是select调用的结果 - 原始STDOUT),然后将 传递回另一个select恢复原来的STDOUT文件句柄。呼。

但现在你明白了(好吧,也许;)),而是这样做:

use IO::Handle;
$fh->autoflush;

答案 1 :(得分:29)

找出任何代码的方法是将它拆开。你知道括号内的东西发生在外面的东西之前。这与你弄清楚其他语言代码在做什么的方式相同。

第一位是:

( select(s), $|=1 )

该列表有两个元素,它们是两个操作的结果:一个选择s文件句柄作为默认值,然后选择一个将$|设置为真值。 $|是每个文件句柄变量之一,仅适用于当前选定的文件句柄(请参阅 The Effective Perler 上的Understand global variables)。最后,您有两个项目的列表:先前的默认文件句柄(select的结果)和1。

下一部分是一个文字列表切片,用于拉出索引0中的项目:

( PREVIOUS_DEFAULT, 1 )[0]

结果是以前默认文件句柄的单个项目。

下一部分获取切片的结果并将其用作另一个select

调用的参数
 select( PREVIOUS_DEFAULT );

因此,实际上,您已经在文件句柄上设置了$|,最后回到了使用默认文件句柄开始的位置。

答案 2 :(得分:20)

select($fh)

选择新的默认文件句柄。见http://perldoc.perl.org/functions/select.html

(select($fh), $|=1)

启用autoflush。见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页面所示。​​

答案 3 :(得分:10)

在另一个场地,我曾经提出过一个更容易理解的版本:

for ( select $fh ) { $| = 1; select $_ }

这保留了紧凑成语的唯一优势,即不需要在周围范围内声明变量。

或者,如果您对$_不满意,可以这样写:

for my $prevfh ( select $fh ) { $| = 1; select $prevfh }

$prevfh的范围仅限于for块。 (但是如果你写Perl,你真的没有理由对$_感到不安。)

答案 4 :(得分:8)

在句柄s上打开缓冲区刷新然后重新选择当前句柄是非常聪明的代码。

有关详情,请参阅perldoc -f select

答案 5 :(得分:2)

请检查perldoc -f select。有关$|的含义,请查看perldoc perlvar

答案 6 :(得分:2)

跳过加载IO :: Handle。

是过分优化的
use IO::Handle;
$fh->autoflush(1);

更具可读性。