I sometimes see Perl code like this:
my ( $variable ) = blah....
What is the point of putting parentheses around a single variable? I thought parentheses were only used when declaring multiple variables, like:
my ( $var1, $var2, $var3 ) = blah...
I sometimes see Perl code like this:
my ( $variable ) = blah....
What is the point of putting parentheses around a single variable? I thought parentheses were only used when declaring multiple variables, like:
my ( $var1, $var2, $var3 ) = blah...
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
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
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
[This answer is also found in table format here.]
The symbol = is compiled into one of two assignment operators:
aassign) is used if the left-hand side (LHS) of a = is some kind of aggregate.sassign) is used otherwise.The following are considered to be aggregates:
(...))@array)@array[...])%hash)@hash{...})my, our or localThere are two differences between the operators.
The two operators differ in the context in which their operands are evaluated.
The scalar assignment evaluates both of its operands in scalar context.
# @array evaluated in scalar context.
my $count = @array;
The list assignment evaluates both of its operands in list context.
# @array evaluated in list context.
my @copy = @array;
# @array evaluated in list context.
my ($first) = @array;
The two operators differ in what they return.
The scalar assignment ...
... in scalar context evaluates to its LHS as an lvalue.
# The s/// operates on $copy.
(my $copy = $str) =~ s/\\/\\\\/g;
... in list context evaluates to its LHS as an lvalue.
# Prints $x.
print($x = $y);
The list assignment ...
... in scalar context evaluates to the number of scalars returned by its RHS.
# Only dies if f() returns an empty list.
# This does not die if f() returns a
# false scalar like zero or undef.
my ($x) = f() or die;
# $counts gets the number of scalars returns by f().
my $count = () = f();
... in list context evaluates to the scalars returned by its LHS as lvalues.
# Prints @x.
print(@x = @y);