Perl中的标量与列表上下文

Perl中的标量与列表上下文,perl,list,scalar,Perl,List,Scalar,我在O'Reilly的书中发现了一个有点奇怪的例子: @backwards = reverse qw/ yabba dabba doo /; print "list context: @backwards\n"; $backward = reverse qw/ yabba dabba doo /; print "scalar1 context: $backward\n"; $notbackward = qw/ yabba dabba doo /; print "scalar2 context:

我在O'Reilly的书中发现了一个有点奇怪的例子:

@backwards = reverse qw/ yabba dabba doo /;
print "list context: @backwards\n";
$backward = reverse qw/ yabba dabba doo /;
print "scalar1 context: $backward\n";
$notbackward = qw/ yabba dabba doo /;
print "scalar2 context: $notbackward\n";
print "print context: ",reverse qw/ yabba dabba doo /;
print "\n";
输出为:

list context: doo dabba yabba
scalar1 context: oodabbadabbay
scalar2 context: doo
print context: doodabbayabba
我不理解的是
scalar1
上下文:

这本书说“反转某物”给出了一个列表上下文,所以我猜
qw/yabba-dabba-doo/
被视为一个列表,
reverse-qw/yabba-dabba-doo/
被视为('doo','dabba','yabba')

因此出现了
$backward=something
,这意味着某物是一个标量,所以我期望得到的结果是“doo-dabba-yabba”,但它是不同的:“oodabbababababay”

我想,原因是不能直接将列表设置为标量。所以我做了
scalar2
测试:只打印列表中最新的项目。为什么?为什么不在scalar1测试中


标量测试输出是如何工作的?

首先,
qw/yabba-dabba-doo/
只是
('yabba','dabba','doo')
的语法糖。他们的意思是一样的

该函数接受一个列表。在列表上下文中,它反转列表。在标量上下文中,它执行
连接(“”,@list)
,然后反转该字符串中的字符并返回它

记得吗

$backward = reverse qw/ yabba dabba doo /;
$notbackward = qw/ yabba dabba doo /;
意味着

reverse
函数提供列表上下文,
$notbackward=
提供标量上下文。这意味着逗号运算符在第一行的列表上下文中,在第二行的标量上下文中。在列表上下文中,创建一个列表。在标量上下文中,它计算两个操作数并返回右边的操作数。这意味着标量上下文中
('yabba','dabba','doo')
的值是
'doo'
,这就是为行分配给
$notbackward
的值:

$backward = reverse qw/ yabba dabba doo /;
您正在从反向请求一个标量。反向的perldoc表示:

在标量上下文中,连接 元素,并返回一个字符串 值中包含所有字符 相反的顺序

因此,它返回每个反转的字母

为了 $notbackward=qw/yabba-dabba-doo/; qw/的perldoc表示:

计算为单词列表 从字符串中提取,使用 嵌入空格作为单词 分隔符。可以理解为 大致相当于:

               split(’ ’, q/STRING/);
不同之处在于它在 编译时,并在标量上下文中使用它 返回列表中的最后一个元素。


因此,请求标量只返回列表中的最后一项。

所有Perl函数,包括您定义的任何
子函数,并且有许多函数基于此上下文更改其行为

除了我的意思之外,关于函数何时以及如何区别对待这两个上下文的约定很少(这对这些问题进行了很好的讨论),因此您需要依赖于每个函数的文档来猜测函数在特定上下文中会做什么

特别是你的四个例子

1. @backwards = reverse qw/ yabba dabba doo /
2. $backward = reverse qw/ yabba dabba doo /
3. $notbackward = qw/ yabba dabba doo /;
4. print ..., reverse qw/ yabba dabba doo /;
这些行为是

1. reverse function, list context:     returns list of the elements in reverse order

2. reverse function, scalar context:   concatenate argument list to a string,
                                       return reverse of that string

3. list assignment to scalar:          returns last element in list (*)

4. also reverse function, list context    same as #1
(*)-注意,对标量的列表赋值不同于对标量的数组赋值——这是列表和数组之间最重要的区别之一:


为了简化其他答案,reverse实际上做了两件独立的事情,列表反转和字符串反转

这被证明是如此混乱,以至于perl6将它们拆分为不同的命名函数

1. reverse function, list context:     returns list of the elements in reverse order

2. reverse function, scalar context:   concatenate argument list to a string,
                                       return reverse of that string

3. list assignment to scalar:          returns last element in list (*)

4. also reverse function, list context    same as #1
@a = ("x", "y", "z");  $n = @a;   # array assignment,  $n is array size, or "3"
$n = ("x", "y", "z");             # list assignment,   $n is last element, or "z"