Introduction
In this blog, we will see what is assignment and parallel assignment and then we will learn about different cases of parallel assignments with examples.
Any assignment expression with multiple lvalues, rvalues, or both are referred to as a parallel assignment. Parallel assignments are useful to write assignment expressions concisely instead of assigning value to different variable in separate lines we can simply assign values in one single line.
So to understand how to write in an efficient way let us learn about parallel assignments in detail.
Parallel Assignment
A parallel assignment is any assignment expression having more than one lvalue/ rvalue or both. More than one lvalues or rvalues are separated from one another with commas. The majority of parallel assignment expressions are easy and self-evident. However, there are some cases that are more complicated.
Note -
- An lvalue is something present on the left hand side of an assignment operator
- Values on the right hand side of an assignment operator are commonly referred to as rvalues
Equal number of lvalues and rvalues
When there are an equal number of lvalues and rvalues, it is a simplest parallel assignment.
For example: x, y, z = 3, 6, 9 # x=3; y=6; z=9
In this example, the first rvalue is assigned to the first lvalue , the second rvalue to the second lvalue, and so on.
One lvalue, multiple rvalues
Ruby constructs an array to hold the rvalues and assigns it to the lvalue when there is only one lvalue and many rvalues.
For example: x = 3, 6, 9 # x = [3,6,9]
You can add a * before the lvalue to keep the semantics and return value of this assignment.
If you wish to avoid the numerous rvalues being aggregated into a single array, put a comma after the lvalue. Ruby will treat it as if there are several lvalues even if there is no lvalue following that comma.
For example: x, = 2, 4, 6 # x = 2; other values are discarded
Multiple lvalues, single array rvalue
Ruby tries to expand the rvalue into a list of values to assign when there are multiple lvalues and only a single rvalue. Ruby expands an array so that each element becomes its own rvalue if the rvalue is an array.
For example: x, y, z = [2, 4, 6] # Same as x,y,z = 2,4,6
Different numbers of lvalues and rvalues
If there are more number of lvalues than rvalues and there is no splat operator, the first rvalue is assigned to the first lvalue, the second rvalue to the second lvalue, and so on until all rvalues have been assigned. Then, for each of the remaining lvalues, nil is assigned, overwriting any previous value.
For example:
x, y, z = 1, 3 # x=1; y=3; z=nil
Suppose there are more rvalues than lvalues and there is no splat operator, then rvalues are assigned to each of the lvalues in sequence, and the leftover rvalues are discarded.
For example: x, y = 1, 3, 9 # x=1; y=3; 9 is not assigned anywhere
The splat operator
Asterisks before rvalues indicate that they are arrays (or objects that resemble arrays) and that the values of each of their elements should be rvalues. The assignment continues after the array elements in the original rvalue list replace the array.
For example: x, y, z = 3, *[6,9] # Same as x,y,z = 3,6,9
Note -
- With Ruby 1.9 in a parallel assignment, the list of rvalues may have any number of splats which can appear at any position in the list
- Double splat is not legal on a nested array: x,y = **[[3,4]] # SyntaxError!
An asterisk before lvalue indicates that all additional rvalues should be collected into an array and assigned to this lvalue and value assigned is always an array, and it may have zero, one, or more elements.
For example:
x,*y = 3, 6, 9 # x=3; y=[6,9]
*x,y = 3, 6 # x=[3]; y=6
x,*y = 3 # x=3; y=[]
Note -
- With Ruby 1.9, one splat operator on the left hand side of a parallel assignment is allowed, though it can be placed anywhere in the list
- In a parallel assignment expression splats may appear on both sides
For example:
x, y, *z = 1, *[2,3,4] # x=1; y=2; z=[3,4]
Parentheses in parallel assignment
Parentheses can be used for sub-assignments in a parallel assignment on the left-hand side. A group of two or more lvalues is originally handled as a single lvalue if it is enclosed in parentheses. The rules of the parallel assignment are applied recursively after determining the corresponding rvalue—that rvalue is assigned to the group of lvalues that was in parentheses.
For example:
x,(y,z) = a, b # effectively two assignments
#x = a
#y,z = b # itself a parallel assignment
Note - The array of rvalues is the return value of a parallel assignment expression (after being augmented by any splat operators).
Check out this article - Balanced Parentheses