我知道我可以通过将输入记录分隔符($/)设置为未定义的值来吸引文件,例如
open my $fh, '<', $filename or die "Cannot read from $file: $!";
my $contents = do { local $/; <$fh> };
Run Code Online (Sandbox Code Playgroud)
但是最近我遇到了一个非常相似但又不同的成语:
open my $fh, '<', $filename or die "Cannot read from $file: $!";
my $contents = do { local $/ = <$fh> };
Run Code Online (Sandbox Code Playgroud)
(请注意,local $/ = <$fh>而不是local $/; <$fh>)。
这两种的工作,并且对两者的CPAN实例与分配所述变体与所述一个无(尽管后者并不奇怪,更为常见)。
但是我的问题是为什么它起作用?作业的变化形式是什么?
PS:我也知道我应该使用例如。File :: Slurper可以吞食文件,但是有时候生活很有趣。
这是未记录的优化的结果,您不应依赖该优化。
通常LHS = RHS评估如下:
正如您所看到的,首先评估赋值的右侧[1]。这允许以下操作:
my $x = 123;
{
my $x = $x * 2;
say $x; # 456
}
say $x; # 123
Run Code Online (Sandbox Code Playgroud)
显然,在你的案例中发生了一些不同的事情——而且没有记录下来。那是因为LHS = <$fh>很特别。readline( )不是从文件读取然后将结果分配给左侧,而是<>直接写入分配左侧的结果。[2]
$/并将其设置为undef您的情况。)$fh被评估。readline进行求值,直接写入赋值左侧的结果。不执行任何分配。
此优化没有记录,您不应该依赖它。
local $/ = uc(<$fh>)例如,这是行不通的。
编译后的代码首先评估右侧:
$ perl -MO=Concise,-exec -e'$L = $R'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <#> gvsv[*R] s <- $R
4 <#> gvsv[*L] s <- $L
5 <2> sassign vKS/2 <- =
6 <@> leave[1 ref] vKP/REFC
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
下面显示了首先评估的右侧:
$ perl -e'sub f :lvalue { CORE::say $_[0]; $x } f("L") = f("R")'
R
L
Run Code Online (Sandbox Code Playgroud)$x = uc(<>)uc(<>)先求值$x,然后执行赋值:
$ perl -MO=Concise,-exec -e'$x = uc(<>)'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <#> gv[*ARGV] s \
4 <1> readline[t3] sK/1 > RHS
5 <1> uc[t4] sK/1 /
6 <#> gvsv[*x] s -> LHS
7 <2> sassign vKS/2
8 <@> leave[1 ref] vKP/REFC
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
$x = uc(<>)评估$xbefore <>,并且它不执行赋值:
$ perl -MO=Concise,-exec -e'$x = <>'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <#> gvsv[*x] s -> LHS
4 <#> gv[*ARGV] s \ RHS
5 <1> readline[t3] sKS/1 /
6 <@> leave[1 ref] vKP/REFC
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
S请注意旁边的(大写)readline以前不存在。这个“特殊”标志告诉我们readline要写入$x.
添加local不会改变任何东西。
$ perl -MO=Concise,-exec -e'local $x = <>'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <#> gvsv[*x] s/LVINTRO
4 <#> gv[*ARGV] s
5 <1> readline[t3] sKS/1
6 <@> leave[1 ref] vKP/REFC
-e syntax OK
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |