Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is a literal list having one element represented unambiguously in perl?

Tags:

perl

I need a function to return a list, which is consumed as sole input list to map BLOCK LIST. I wrote return (6); because I wanted to return a list having one element, but this looks same as a scalar enclosed in parentheses. Will it be interpreted the way I want? Need I use ugly things like: return @{[6]}; to enforce my intention?

like image 803
pii_ke Avatar asked Dec 29 '14 11:12

pii_ke


People also ask

What does @_ mean in Perl?

Using the Parameter Array (@_) Perl lets you pass any number of parameters to a function. The function decides which parameters to use and in what order.

What is a list in Perl?

A Perl list is a sequence of scalar values. You use parenthesis and comma operators to construct a list. Each value is the list is called list element. List elements are indexed and ordered. You can refer to each element by its position.


1 Answers

There is no ambiguity here, and you cannot return a list unconditionally.

In Perl 5, every expression, including a subroutine call, has a context, which is either list context (returning zero or more values) or scalar context (returning exactly one value). A return statement propagates the context of the subroutine call to the expression in the return statement. Let's suppose you're trying to return a list with several elements:

return (6, 7, 8);

This is not guaranteed to be a list. If the sub is called in scalar context, then the comma expression in the return statement is in scalar context also, and the behavior of the comma expression in scalar context is to return the rightmost value, here 8.

If you instead used a temporary array,

return @{[6, 7, 8]}

then if it is called in scalar context you will get the behavior of arrays in scalar context, which is to return the number of elements in the array.

All of the above applies to one-element lists just as much as the three-element lists in the example.

Some general facts:

  • There is no way to forcibly return a list — you can only return what the caller asks for.

  • There is no systematic choice for what happens if you invoke a list-y thing in scalar context — the number of elements in the list which would be returned in list context is a common choice, but not universal.

  • If you want to have a well-specified subroutine, you cannot say “it always returns a list”; you must specify what happens when it is required to return a scalar. (You could decide that it will always die, if you wanted.)

  • If you want to make an explicit choice based on whether the call is in scalar or list context, you can use the poorly-named builtin wantarray, which returns true if the subroutine was called in list context.

This is the closest thing to what you asked for that can actually exist. Note that there are no parentheses — parentheses don't affect context.

die "can't be scalar" unless wantarray;
return 6;
like image 78
Kevin Reid Avatar answered Sep 28 '22 07:09

Kevin Reid