0

这段代码中的 [0] 做了什么:

select((select(LOG_FILE),$!=1)[0]);
4

2 回答 2

3

更新:十年前我回答了这个问题!“select((select(s),$|=1)[0])” 在 Perl 中有什么作用?


您正在查看对列表的单个元素访问。括号中的表达式生成某种列表,并[0]从列表中选择一项。

这段代码是一个非常古老的习惯用法,用于设置每个文件句柄有点全局变量。我认为您可能是指$|(自动刷新设置)而不是$!.

首先,请记住 Perl 有“默认文件句柄”的概念。这开始是标准输出,但您可以更改它。这就是它的select作用。

接下来,意识到每个文件句柄都知道自己的各种设置;这些由特殊变量表示,例如$|(参见perlvar 的“与文件句柄相关的变量”部分)。当您更改这些变量时,它们将应用于当前的默认文件句柄。

所以,你在这个习语中看到的是一个select改变默认文件句柄的内部。您更改默认值,然后设置$|为您想要的任何值。它看起来有点奇怪,因为你有两个用逗号而不是分号分隔的表达式,use 语句分隔符:

(select(LOG_FILE), $|=1)

由此,成语想要 ; 的结果select。这是以前的默认文件句柄。为此,您需要该列表中的第一项。那在索引 0 中:

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

整个表达式的结果是以前的默认文件句柄,您现在要恢复它。用外部做到这一点select

select((select(LOG_FILE), $|=1)[0]);

你可以用一个中间变量来写:

my $previous = select LOG_FILE;
$| = 1;
select($previous);

如果你自己写新东西,你可以使用标量变量作为文件句柄,然后调用它的autoflush方法:

open my $log_file_fh, '>', $log_filename or die ...;
$log_file_fh->autoflush(1);
于 2018-12-29T18:48:08.477 回答
2

( LIST1 )[ LIST2 ]是一个列表切片。在列表上下文中,它计算为LIST1指定的元素LIST2

在这种情况下,它返回select.


select((select(LOG_FILE),$!=1)[0]);

应该

select((select(LOG_FILE),$|=1)[0]);

后者启用LOG_FILE文件句柄的自动刷新。可以写得更清楚如下:

use IO::Handle ();       # Only needed in older versions of Perl.
LOG_FILE->autoflush(1);

顺便说一句,你不应该使用这样的全局变量。代替

open LOG_FILE, ...

你应该使用

open my $LOG_FILE, ...
于 2018-12-29T03:10:27.940 回答