A neat feature of ruby is the ability to assign more than one LValue on a single line, like that :
a, b = 5, 10
The pickaxe book has a great exemple of use for this feature : It’s when you want to swap two values.
Instead of having to use a temporary variable an go with the following typical approach :
temp = a
a = b
b = temp
You can screw the temp variable and just write :
a, b = b, a
It works because the right values are all evaluated before being assigned to their corresponding left variable. In other words, one assignement doesn’t alter the others.
While these parallel assignements are great, the problem strikes when they become too complicated and hard to understand.
That same pickaxe book goes mad and push the feature a little too far for my taste at page 93 :
b, (c,d), e = 1,[2,3,4],5
I understand this was just an exemple demonstrating the various possibilities, but I personally wouldn’t recommend anyone to ever do that. Putting more than one instruction on a single line may be fun… but we have to learn when to stop.
But let’s understand it anyway :
This example demonstrates that parallel assignements can be nested, meaning that c and d are treated like a single position on the left side (the 2nd one).
Results after that crazy assignement
1 is assigned to b
2 is assigned to c
3 is assigned to d
4 is lost
5 is assigned to e
Since the left variables c and d are located at the second position, ruby extracts the RValue located at the 2nd position. That RValue need to be an array or else every LValue specified in the parenthesized terms, at the exception of the first one, would be initialized to nil. c and d are located at a single position on the left side, so they map to a single position on the right side.
So that’s how it works, but I wouldn’t do something like that anyway. Most of the time, I try to follow these 2 simple guidelines before deciding to use parallel assignements :
1. LValues should be related to each other
I would not do this :
time_of_the_day, favorite_color, clowns = Time.now, :blue, "Not funny"
But I could do this :
favorite_color, almost_favorite_color = :blue, :yellow
2. For simple things only. It should’nt hurt code readability
We like ruby for it’s expressiveness. Too much stuff going on on a single line kills readability. It’s never good when a programmer stare at your code for 2-3 minutes trying to understand some mad one-liners.
One-line conditionals are another code construct that should be kept simple. I’ve seen some nasty ones where I’ve had to write down the nested if-else logic on a piece of paper just to understand one line of code!