Perl 中的标量与列表上下文

发布于 2024-10-20 03:11:15 字数 910 浏览 2 评论 0原文

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风蛊 2024-10-27 03:11:16

对于该行:

$backward = reverse qw/ yabba dabba doo /;

您在此处从反向请求标量。反向的 perldoc 说:

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

所以它返回每个字母的反转。

为了
$notbackward = qw/ yabba dabba doo /;
qw // 的 perldoc 说:

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

 split(' ', q/STRING/);

区别在于它生成一个真实的列表
编译时,并且在标量上下文中
返回列表中的最后一个元素。

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

For the line:

$backward = reverse qw/ yabba dabba doo /;

You are requesting a scalar here from reverse. The perldoc for reverse says:

In scalar context, concatenates the
elements of LIST and returns a string
value with all characters in the
opposite order.

So it returns each of the letters reversed.

For
$notbackward = qw/ yabba dabba doo /;
the perldoc for qw// says:

Evaluates to a list of the words
extracted out of STRING, using
embedded whitespace as the word
delimiters. It can be understood as
being roughly equivalent to:

               split(’ ’, q/STRING/);

the differences being that it generates a real list at
compile time, and in scalar context it
returns the last element in the list.

So requesting the scalar only returns the last item in the list.

别把无礼当个性 2024-10-27 03:11:16

为了简化其他答案,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.

月亮坠入山谷 2024-10-27 03:11:15

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

reverse 函数采用一个列表。在列表上下文中,它反转列表。在标量上下文中,它执行 join('', @list) 然后反转该字符串中的字符并返回它。

请记住,这

$backward = reverse qw/ yabba dabba doo /;
$notbackward = qw/ yabba dabba doo /;

意味着

$backward = reverse ('yabba', 'dabba', 'doo');
$notbackward = ('yabba', 'dabba', 'doo');

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

$backward = reverse qw/ yabba dabba doo /;
$notbackward = qw/ yabba dabba doo /;

means

$backward = reverse ('yabba', 'dabba', 'doo');
$notbackward = ('yabba', 'dabba', 'doo');

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.

香草可樂 2024-10-27 03:11:15

所有 Perl 函数,包括您定义的任何可以检测是否它们在“标量”或“列表”上下文中被调用,并且有许多函数可以根据此上下文更改其行为。

除了“按我的意思做”之外,关于函数何时以及如何以不同方式处理两个上下文(这个 perlmonks 上的整个线程对这些问题进行了很好的讨论),因此您需要依赖每个函数的文档来猜测函数在特定上下文中将执行的操作。

具体来说,对于您的四个示例,

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

(*) - 注意列表分配给标量不同于数组分配给标量 - 这是列表之间最重要的区别之一> 和数组

@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"

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,

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 /;

the behaviors are

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

(*) - note list assignment to scalar is different from array assignment to scalar -- this is one of the most important distinctions between lists and arrays:

@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"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文