2 perl
他在《Perl 编程》第 90 页中说道:
@ary = (1, 3, sort 4, 2);
print @ary;
Run Code Online (Sandbox Code Playgroud)
排序右侧的逗号在排序之前计算,而左侧的逗号在排序之后计算。...列表运算符倾向于吞噬..然后表现得像一个简单的术语”
@ary通过打印扩展时会发生这种情况吗?(4 and 2)。逗号到底是如何被评估的?这样该语句就变成 (1, 3, 2, 4) 一个被分配的列表。逗号只是充当列表分隔符而不是运算符!事实上,在第 108 页,他说:不要将逗号的标量上下文使用与列表上下文使用混淆。什么是向左和向右列表运算符?print @ary是向右列表运算符??那么它的优先级很低吗?
打印($foo,退出);
这里,优先级是如何评估的?print 是一个列表运算符,看起来像一个函数,所以它应该首先运行!它有两个参数$foo和exit..那么为什么 exit 不被视为字符串???毕竟优先级打印(列表运算符)具有更高的优先级?
print $foo, exit;
Run Code Online (Sandbox Code Playgroud)
在这里,您有 print 和 , 运算符,但列表运算符具有更高的优先级..所以.. exit 应该被视为字符串 - 为什么不呢?
print ($foo & 255) + 1, "\n";
Run Code Online (Sandbox Code Playgroud)
在这里,因为它是一个列表运算符,所以它打印$foo & 255上面提到的exit东西不应该发生类似的事情吗?
当对 Perl 如何解析构造有疑问时,您可以通过B::Deparse模块运行代码,这将从编译的内部表示生成 Perl 源代码。对于你的第一个例子:
$ perl -MO=Deparse,-p -e '@ary = (1, 3, sort 4, 2); print @ary;'
(@ary = (1, 3, sort(4, 2)));
print(@ary);
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,sort将两个参数放在右侧。
就执行顺序而言,您可以通过B::Concise模块找到它(我已添加注释):
$ perl -MO=Concise,-exec -e '@ary = (1, 3, sort 4, 2); print @ary;'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark s # start of list
4 <$> const[IV 1] s # 1 is added to list
5 <$> const[IV 3] s # 3 is added to list
6 <0> pushmark s # start of sort's argument list
7 <$> const[IV 4] s # 4 is added to sort's argument list
8 <$> const[IV 2] s # 2 is added to sort's argument list
9 <@> sort lK # sort is run, and returns its list into the outer list
a <0> pushmark s
b <#> gv[*ary] s
c <1> rv2av[t2] lKRM*/1
d <2> aassign[t3] vKS/COMMON # the list is assigned to the array
e <;> nextstate(main 1 -e:1) v:{
f <0> pushmark s # start of print's argument list
g <#> gv[*ary] s # the array is loaded into print's argument list
h <1> rv2av[t5] lK/1
i <@> print vK # print outputs it's argument list
j <@> leave[1 ref] vKP/REFC
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
对于第二个例子:
$ perl -MO=Deparse,-p -e 'print $foo, exit;'
print($foo, exit);
-e syntax OK
$ perl -MO=Concise,-exec -e 'print $foo, exit;'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark s
4 <#> gvsv[*foo] s # add $foo to the argument list
5 <0> exit s # call `exit` and add its return value to the list
6 <@> print vK # print the list, but we never get here
7 <@> leave[1 ref] vKP/REFC
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,exit内置函数在尝试组装 的参数列表时运行print。由于exit导致程序退出,该print命令永远不会运行。
最后一个:
$ perl -MO=Deparse,-p -e 'print ($foo & 255) + 1, "\n";'
((print(($foo & 255)) + 1), '???'); # '???' means this was optimized away
-e syntax OK
$ perl -MO=Concise,-exec -e 'print ($foo & 255) + 1, "\n";'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark v
4 <0> pushmark s
5 <#> gvsv[*foo] s
6 <$> const[IV 255] s
7 <2> bit_and[t2] sK
8 <@> print sK
9 <$> const[IV 1] s
a <2> add[t3] vK/2
b <@> list vK
c <@> leave[1 ref] vKP/REFC
-e syntax OK
Run Code Online (Sandbox Code Playgroud)