I sometimes see Perl code like this:
my ( $variable ) = blah....
What is the point of putting parentheses around a single variable? I thou
I have posted an in-depth explanation on the subject on another site.
[I can't post it here. StackOverflow doesn't support tables. Not that anyone usually has a problem with offsite linking to documentation.]
The parentheses create a list context which affects how the right hand side of the assignment is evaluated.
Compare
my $x = grep { /s/ } qw(apples bananas cherries);
print $x;
with
my ($x) = grep { /s/ } qw(apples bananas cherries);
print $x;
You will often use this construction when you just want to grab the first element of a list and discard the rest.
I'm not a Perl pro (by all means, I'm not), but AFAIK it has to do with lists.
Perl has different contexts (scalar, list). Using ($var)
switches to list context, $var
is scalar context.
my $var = (1, 2, 4); # $var = 4 (last element)
my ($var) = (1, 2, 4); # $var = 1
Please downvote this answer, if it is totally wrong :)
There are several scenarios when there is a difference:
When array is on right side
my @array = ('a', 'b', 'c');
my $variable = @array; # 3 size of @array
my ($variable) = @array; # 'a' $array[0]
When list is on right side
my $variable = qw/ a b c d /; # 'd' last item of the list
my ($variable) = qw/ a b c d /; # 'a' first item of the list
Subroutine with variable (array/scalar) return value
sub myFunction {
...
return (wantarray() ? @array : $scalar);
}
my $variable = myFunction(...); # $scalar from the subroutine
my ($variable) = myFunction(...); # $array[0] from the subroutine
You are confusing two different things. First off, when using my
to declare several variables, you need to use parentheses:
my $foo, $bar;
Does not work, as it is considered to be two different statements:
my $foo;
$bar;
So you need parentheses to group together the argument into an argument list to the function my
:
my($foo, $bar);
Secondly, you have explicit grouping in order to invoke list context:
$foo, $bar = "a", "b"; # wrong!
Will be considered three separate statements:
$foo;
$bar = "a";
"b";
But if you use parentheses to group $foo
and $bar
into a list, the assignment operator will use a list context:
($foo, $bar) = ("a", "b");
Curiously, if you remove the RHS parentheses, you will also experience a hickup:
($foo, $bar) = "a", "b"; # Useless use of a constant (b) in void context
But that is because the =
operator has higher precedence than comma ,
, which you can see in perlop. If you try:
my @array = ("a", "b");
($foo, $bar) = @array;
You will get the desired behaviour without parentheses.
Now to complete the circle, lets remove the list context in the above and see what happens:
my @array = ("a", "b");
$foo = @array;
print $foo;
This prints 2
, because the array is evaluated in scalar context, and arrays in scalar context return the number of elements they contain. In this case, it is 2
.
Hence, statements such as these use list context:
my ($foo) = @array; # $foo is set to $array[0], first array element
my ($bar) = ("a", "b", "c"); # $bar is set to "a", first list element
It is a way of overriding the scalar context which is implied in scalar assignment. For comparison, these assignments are in scalar context:
my $foo = @array; # $foo is set to the number of elements in the array
my $bar = ("a", "b", "c"); # $bar is set to "c", last list element