标量上下文中的列表会产生列表的最后一个元素。这是一个谎言,因为(俗话说)你不能在标量上下文中有一个列表。看起来像标量上下文中的列表实际上是标量上下文中的逗号运算符,它在标量上下文中具有不同的行为。
然而,在这个逻辑中似乎存在一个循环漏洞:空列表(有时称为空列表)。字符()
为defined to be the null list by perldoc perlglossary
。构造
my $s = ();
是有效代码,并将undef
返回$s
。这似乎没有在perldoc
中的任何地方记录(我没有检查过Camel),但是很多代码都依赖于它,所以我认为它就在这里。
既然序言已经完成,那么问题是:如果我们不能在标量上下文中有一个列表,那么我们在标量上下文中将什么称为空列表,什么是不将其称为列表的理由(因为那里在标量语境中没有逗号?)
如果您喜欢这个问题,您可能也喜欢discussion going on in P5P。
答案 0 :(得分:7)
列表是一个非常通用的词。您可能会引用列表运算符或列表值。
代码中没有逗号,因此没有列表运算符。
代码中没有列表上下文,因此没有列表值。
因此,
中没有列表my $s = ();
括号永远不会创建列表
(仅在赋值运算符的LHS上间接进行。)
我们在标量上下文中称为空列表
Perl将其称为“存根”(如下所示),这就是它的真实含义。它是代码中的占位符,其中几乎没有任何东西是不允许的。
存根由“空括号”表示,因此它是另一个名称。
我称之为糟糕的代码。如果您想指定undef
,请指定undef
。
标量上下文中的列表会产生列表的最后一个元素。
不,那是真的。列表值不能存在于标量上下文中,因此保留列表运算符。
list运算符又称逗号运算符,在标量上下文中返回列表的最后一个元素。
比较以下内容。没有提到清单:
>perl -MO=Concise -e"my $s = ();"
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
5 <2> sassign vKS/2 ->6
3 <0> stub sP ->4
4 <0> padsv[$s:1,2] sRM*/LVINTRO ->5
-e syntax OK
提到了一个清单
>perl -MO=Concise -e"my @a = ();"
7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
6 <2> aassign[t2] vKS ->7
- <1> ex-list lK ->4
3 <0> pushmark s ->4
- <0> stub lP ->-
- <1> ex-list lK ->6
4 <0> pushmark s ->5
5 <0> padav[@a:1,2] lRM*/LVINTRO ->6
-e syntax OK
......它与parens无关
>perl -MO=Concise -e"my @a = 's';"
8 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
7 <2> aassign[t2] vKS ->8
- <1> ex-list lK ->5
3 <0> pushmark s ->4
4 <$> const[PV "s"] s ->5
- <1> ex-list lK ->7
5 <0> pushmark s ->6
6 <0> padav[@a:1,2] lRM*/LVINTRO ->7
-e syntax OK
答案 1 :(得分:1)
它更像是一个无价值的表达式,相当于undef
。还有一些例子:
$ perl -we 'print scalar( () )'
Use of uninitialized value in print at -e line 1.
$ perl -we 'print 0+()'
Use of uninitialized value in addition (+) at -e line 1.