Perl 中的标量与列表上下文
我在 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 / 被视为一个列表,而 反向 qw/ yabba dabba doo /
被视为 ('doo', 'dabba', 'yabba')。
因此出现了 $backward = Something
,这意味着某些东西是标量,所以我期待结果“doo dabba yabba”,但它是不同的:“oodabbadabbay”。
我想,原因是因为不能直接将列表设置为标量。所以我做了 scalar2
测试:仅打印列表中的最新项目。为什么?为什么不在 scalar1 测试中呢?
标量测试输出如何工作?
I found an example in an O'Reilly book a little weird:
@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";
The output is:
list context: doo dabba yabba
scalar1 context: oodabbadabbay
scalar2 context: doo
print context: doodabbayabba
The one I do not understand is the scalar1
context:
The book says 'reverse something' gives a list context, so I guess qw/ yabba dabba doo /
is seen as a list and reverse qw/ yabba dabba doo /
as ('doo', 'dabba', 'yabba').
So comes the $backward = something
which implies something is a scalar, so I was expecting the result 'doo dabba yabba', but it is différent: 'oodabbadabbay'.
I thought, the reason was because one cannot set a list to a scalar directly. So I made the scalar2
test: only the latest item in the list is printed. Why? Why not in the scalar1 test?
How do the scalar tests output work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于该行:
您在此处从反向请求标量。反向的 perldoc 说:
所以它返回每个字母的反转。
为了
$notbackward = qw/ yabba dabba doo /;
qw // 的 perldoc 说:
因此请求标量仅返回列表中的最后一项。
For the line:
You are requesting a scalar here from reverse. The perldoc for reverse says:
So it returns each of the letters reversed.
For
$notbackward = qw/ yabba dabba doo /;
the perldoc for qw// says:
So requesting the scalar only returns the last item in the list.
为了简化其他答案,reverse 实际上做了两个单独的事情,列表反转和字符串反转。
事实证明,这非常令人困惑,以至于 perl6 将它们分成不同名称的函数。
To simplify the other answers, reverse actually does two separate things, list reversal and string reversal.
This has proven to be so confusing that perl6 splits them out to differently named functions.
首先,
qw/ yabba dabba doo /
只是('yabba', 'dabba', 'doo')
的语法糖。他们的意思是一样的。reverse 函数采用一个列表。在列表上下文中,它反转列表。在标量上下文中,它执行
join('', @list)
然后反转该字符串中的字符并返回它。请记住,这
意味着
reverse
函数提供列表上下文,而$notbackward =
为我们提供标量上下文。这意味着逗号运算符位于第一行的列表上下文中,第二行的标量上下文中。在列表上下文中,逗号运算符 创建一个列表。在标量上下文中,它计算两个操作数并返回右侧的操作数。这意味着标量上下文中('yabba', 'dabba', 'doo')
的值为'doo'
,这就是分配给$ 的值不落后。
First of all,
qw/ yabba dabba doo /
is just syntactic sugar for('yabba', 'dabba', 'doo')
. They mean the same thing.The reverse function takes a list. In list context, it reverses the list. In scalar context, it does
join('', @list)
and then reverses the characters in that string and returns it.Remember that
means
The
reverse
function supplies list context and$notbackward =
gives us scalar context. This means that the comma operator is in list context on the first line and scalar context on the second. In list context, the comma operator creates a list. In scalar context, it evaluates both operands and returns the right hand one. This means that the value of('yabba', 'dabba', 'doo')
in scalar context is'doo'
, and that's what's assigned to$notbackward
.所有 Perl 函数,包括您定义的任何
子
,可以检测是否它们在“标量”或“列表”上下文中被调用,并且有许多函数可以根据此上下文更改其行为。除了“按我的意思做”之外,关于函数何时以及如何以不同方式处理两个上下文(这个 perlmonks 上的整个线程对这些问题进行了很好的讨论),因此您需要依赖每个函数的文档来猜测函数在特定上下文中将执行的操作。
具体来说,对于您的四个示例,
行为是
(*) - 注意列表分配给标量不同于数组分配给标量 - 这是列表之间最重要的区别之一> 和数组:
All Perl functions, including any
sub
's that you define, can detect whether they are being called in "scalar" or "list" context, and there are many functions that change their behavior based on this context.There are very few conventions, other than Do What I Mean, about when and how a function treats the two contexts differently (this whole thread on perlmonks has a good discussion of these issues), so you need to rely on the documentation of each function to guess what a function will do in a particular context.
Specifically for your four examples,
the behaviors are
(*) - note list assignment to scalar is different from array assignment to scalar -- this is one of the most important distinctions between lists and arrays: