Skip to content

Commit c3311f9

Browse files
authored
Merge pull request #3137 from threadless-screw/item_list_assignments
Clarification of item and list assignment syntax and evaluation.
2 parents 3cd20ae + 7ebb005 commit c3311f9

File tree

1 file changed

+88
-58
lines changed

1 file changed

+88
-58
lines changed

doc/Language/variables.pod6

Lines changed: 88 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -87,72 +87,102 @@ L<sigilless variables|#Sigilless_variables>.
8787
=head2 Item and list assignment
8888
8989
There are two types of variable assignment, I<item assignment> and I<list
90-
assignment>. Both use the equal sign C<=> as operator. The syntax of the
91-
left-hand side determines whether an C<=> means item or list assignment.
92-
93-
Item assignment places the value from the right-hand side into the variable
94-
(container) on the left.
95-
96-
List assignment leaves the choice of what to do to the variable on the left.
97-
98-
For example, L<Array|/type/Array> variables (C<@> sigil) empty themselves on
99-
list assignment and then put all the values from the right-hand side into
100-
themselves.
101-
102-
The type of assignment (item or list) is decided by the first context
103-
seen in the current expression or declarator:
104-
105-
my $foo = 5; # item assignment
106-
say $foo.perl; # OUTPUT: «5␤»
107-
108-
my @bar = 7, 9; # list assignment
109-
say @bar.^name; # OUTPUT: «Array␤»
110-
say @bar.perl; # OUTPUT: «[7, 9]␤»
111-
112-
(my $baz) = 11, 13; # list assignment
113-
say $baz.^name; # OUTPUT: «List␤»
114-
say $baz.perl; # OUTPUT: «$(11, 13)␤»
115-
116-
Thus, the behavior of an assignment contained within a list assignment depends
117-
on the expression that contains it or declarator that precedes it.
118-
119-
For instance, if the contained assignment is a declarator, item assignment
120-
is used, which has tighter precedence than both the comma and the list
121-
assignment:
90+
assignment>.
91+
92+
An item assignment copies a single value from the right-hand side into a Scalar
93+
variable on the left. An assignment to anything other than a simple Scalar
94+
variable is parsed as a list assignment. A list assignment leaves the choice of
95+
what the assignment operation entails to the variable on the left. For example,
96+
L<Array|/type/Array> variables (C<@> sigil) empty themselves on list assignment,
97+
and then iteratively copy all values from the right-hand side into themselves as
98+
elements.
99+
100+
The two types of assignment both use the equal sign C<=> as their operator and
101+
are both right associative, but differ in operator precedence: item assignment
102+
has a higher precedence level (level: Item assignment) than list assigment
103+
(level: List prefix). In situations in which a comma-separated list of elements
104+
is assigned, these precedences should in particular be contrasted with that of
105+
the comma operator C<,> which sits in between. So without any list-delimiting
106+
parentheses (or other construct to hold the list's elements together), item
107+
assignment will only assign the first element of the specified list, and not the
108+
full list.
109+
110+
In an assignment expression the context of the left-hand side determines whether
111+
an C<=> means item or list assignment. As mentioned, item assignment is
112+
restricted to simple Scalar variables. Accordingly, assignment to a Scalar
113+
container (scalar-context) triggers item assignment, unless the Scalar is
114+
explicitly put in list-context by surrounding parentheses C<( )>:
115+
116+
my $a;
117+
$a = 1,2,3; # item assignment to Scalar
118+
say $a; # OUTPUT: «1␤» ( '=' has higher precedence than ',' )
119+
120+
my $b = 1,2,3; # item assignment to Scalar (same as preceding example)
121+
say $b; # OUTPUT: «1␤»
122+
123+
my $c;
124+
($c) = 4,5,6; # list assignment to Scalar; '( )' is list-contextualizer
125+
say $c; # OUTPUT: «(4,5,6)␤»
126+
127+
(my $d) = 4,5,6; # list assignment to Scalar (same as preceding example)
128+
say $d; # OUTPUT: «(4,5,6)␤»
129+
130+
Assignment to a List container (list-context) always triggers list assignment:
131+
132+
my @e;
133+
@e = 7,8,9; # list assignment to Array
134+
say @e; # OUTPUT: «[7,8,9]␤»
135+
136+
my $f;
137+
($f,) = 7,8,9; # list assignment to List with one element
138+
say $f; # OUTPUT: «7␤»
139+
say ( ($f,) ).VAR.WHAT; # OUTPUT: «(List)␤»
140+
141+
# ATTENTION: special declaration syntax!
142+
my ($g) = 7,8,9; # list assignment to List with one element
143+
say $g; # OUTPUT: «7␤»
144+
say ( my ($g) ).VAR.WHAT # OUTPUT: «(List)␤»
145+
146+
The last two examples above are simple I<destructuring assignments> that select
147+
the first item of the right-hand side list. See for a more elaborate discussion
148+
of destructuring assignments in the context of variable declarations the section
149+
on L<declaring a list of variables with lexical or package
150+
scope|/language/variables#index-entry-declaring_a_list_of_variables>.
151+
152+
Chained assignments are parsed having regard to the precedence of the assignment
153+
operators and, where applicable, their right associativity. For instance, in the
154+
example below there is one chained assignment statement comprising two
155+
assignment operators. The assignment to C<@array> is a list assignment having a
156+
lower precedence than the item assignment to the Scalar variable C<$num>. The
157+
assignment expression involving the item assignment to the Scalar variable
158+
C<$num> is thus evaluated first. It returns the assigned value C<42>, which in
159+
turn forms part of the List C<(42, "str")> constructed by the comma operator
160+
that also has a higher precedence than the list assignment. Finally, the
161+
List C<(42, "str")> is list-assigned to C<@array>:
122162
123163
my @array;
124-
@array = my $num = 42, "str"; # item assignment: uses declarator for $num
164+
@array = my $num = 42, "str"; # parsed as @array = ( (my $num = 42), "str )
125165
say @array.perl; # OUTPUT: «[42, "str"]␤» (an Array)
126166
say $num.perl; # OUTPUT: «42␤» (a Num)
127167
128-
Similarly, if the internal or contained assignment is an expression that is
129-
being used as an initializer for a container declarator, the context of the
130-
internal expression determines the assignment type:
168+
Here's a variant:
131169
132-
my $num;
133-
my @array = $num = 42, "str"; # item assignment for $num: uses expression
134-
say @array.perl; # OUTPUT: «[42, "str"]␤» (an Array)
135-
say $num.perl; # OUTPUT: «42␤» (a Num)
170+
my ( @foo, $bar );
171+
@foo = ($bar) = 42, "str"; # parsed as @foo = ( $bar = (42, "str") )
172+
say $bar.perl; # OUTPUT: «$(42, "str")␤» (a List)#
173+
say @foo.perl; # OUTPUT: «[(42, "str"),]␤» (an Array)
136174
137-
The same result would be obtained if C<@array> is declared before the
138-
assignment; C<$num> would be still item-assigned, C<@array> list-assigned; the
139-
assignment expression is parsed as C<@array = (($num = 42), "str")>, because
140-
item assignment has tighter precedence than the comma. However, let's see what
141-
happens if the internal variable assignment is in a list context:
175+
In this case, the list contextualizer C<( )> puts C<$bar> in a list context, and
176+
thus triggers a list assignment to the Scalar variable C<$bar>. This means that
177+
there are two chained list assignments, both having a lower precedence than the
178+
comma operator C<,> that constructs the List C<(42, "str")>. Due to their right
179+
associativity, the list assignment expression that is evaluated first is the
180+
assignment to C<$bar>, which returns the assigned value C<$(42, "str")>, i.e. a
181+
Scalar containing a two-element List. This value is in turn list-assigned to
182+
C<@array>, such that it becomes a Array with a single element, namely a List.
142183
143-
=for code
144-
my ( @foo, $bar );
145-
@foo = ($bar) = 42, "str"; # list assignment for $bar: uses parentheses
146-
say @foo.perl; # OUTPUT: «[(42, "str"),]␤» (an Array)
147-
say $bar.perl; # OUTPUT: «$(42, "str")␤» (a List)#
148-
149-
In this case, C<()> is the list contextualizer, putting the assignment to
150-
C<$bar> in a list context; C<$bar> then I<decides> to include all the items to
151-
the right hand side of the C<=> sign; this is still included in a list
152-
assignment to C<@foo>, which then becomes an array with a single element, a
153-
C<List>.
154-
155-
See L<operators|/language/operators> for more details on precedence.
184+
See L<operators|/language/operators> for more details on precedence and
185+
associativity.
156186
157187
=head2 Sigilless variables
158188
X<|\ (sigilless variables)>

0 commit comments

Comments
 (0)