Scalar vs list context in Perl

放肆的年华 提交于 2019-12-03 17:15:34

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.

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.

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"

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!