在 perl 中,一个 liner slurp 模式是 0777
我希望它等于下面的脚本
open my $fh, "<","file";
local $/;
my $s = <$fh>; #now whole file stored into the $s
这里我们没有使用任何循环将所有元素存储在一起(单个数据)。
但是在 perl one liner 中,为什么我们使用 -p|-n
开关来启用 slurp 模式(-0777
)?这里的性能增益是什么。?
-p | -n
用于循环目的。那么一个类轮的实际表现是像下面的脚本还是其他什么?
open my $fh, "<","file";
my $s;
while (<$fh>)
{
$s.=$_;
}
print $s;
最佳答案
没有 -n
或 -p
没有隐含的 while (<>)
循环所以默认 $_
没有设置,也没有读取 STDIN。如果我们想拥有 <>
和 $_
默认情况下,在 slurp 模式下,我们需要这些开关之一以及 -0777
,它本身只是(取消)设置$/
.这个
echo "hello" | perl -0777 -e 'print'
什么都不打印,并且使用 -w
它警告 Use of uninitialized value $_
.现在这个
echo "hello" | perl -0777 -e '$v = <>; print $v'
打印 hello
. STDIN
可以读入变量,所以 'slurp' 是 on。
就这相当于,仅仅是-0777
只做 $/ = undef
.如果我们添加一个读取
# use warnings;
local $/;
<>;
print;
<>
一口气读完所有内容,但没有默认输入和模式搜索空间 (variable $_
)
所以读取的内容没有分配给任何东西。随着警告的出现,我们可以听到它。 (感谢 Jonathan Leffler 在评论中提到 STDIN。)
相当于使用 -n
的代码是
while (defined($_ = <ARGV>)) { }
所以我们得到标准输入和$_
设置。运行perl -MO=Deparse -n -e 1
看看这些。
在 perlvar列出了“...Perl 将假定 $_
...”时的条件。最后一颗子弹
The default place to put the next value or input record when a
<FH>
,readline
,readdir
oreach
operation's result is tested by itself as the sole criterion of awhile
test. Outside awhile
test, this will not happen.
与 -n
或 -p
开关我们得到这个,以及所有的标准输入。
请注意,您的示例并不完全等效,因为它确实分配了。
评论问题中的具体陈述。
slurp 没有被这些开关“启用”——它是由 -0777
设置的。旗帜。我们使用它们是因为我们获得了自动标准输入和 $_
和他们一起。
关于perl - 为什么在 perl one liner 中以 slurp 模式使用 -p|-n ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37582501/