Reputation: 73
I'm stuck on a homework problem, and found a solution by looking at someone's work. Problem is I don't understand it. Here's the code
ordering, @title_header = {:order => :title}, 'hilite'
What is happening to 'ordering' in this case? I tried googling to see if that's a method, but couldn't find anything.
Upvotes: 0
Views: 152
Reputation: 1225
This is "parallel assignment".
Parallel assignment in Ruby is what happens when there is more than 1 lvalue (i.e., value on the left-hand side of the equals sign) and/or more than 1 rvalue (value on the right-hand side of the equals sign).
To understand parallel assignment, there are various cases to consider.
The first, simplest case is when there is 1 lvalue and multiple rvalues. For example:
> a = 1, 2
> a
=> [1, 2]
All that's happening is the right-hand comma-separated list of values is converted into an array and assigned to the left-hand variable.
The second case is when there are the same number of lvalues and rvalues. For example:
> a,b = 'foo', 'bar'
> a
=> "foo"
> b
=> "bar"
This is also pretty straightforward -- you simply evaluate each item on the right hand, then assign it to its corresponding variable on the left-hand side, in order.
The third case is when the rvalue is an array, and that array's elements are distributed (or "expanded") among multiple lvalues. For example:
> a, b = ['foo', 'bar']
> a
=> "foo"
> b
=> "bar"
This is effectively the same as case #2, above, except in this case explicitly employing array syntax.
The fourth case is when there are multiple values on both sides, and there are more lvalues than rvalues. For example:
> a, b, c = 'foo', 'bar' # Note only 2 values on the right
> a
=> 'foo'
> b
=> 'bar'
> c
=> nil
As you can see, Ruby did the best it could to distribute the values, but ran out of them and was forced to assign nil
to the last variable on the left.
The fifth case is when there are multiple values on both sides, and there are fewer lvalues than rvalues. For example:
> a, b = 'foo', 'bar', 'baz' # Note only 2 values on the left
> a
=> 'foo'
> b
=> 'bar'
Again, Ruby did the best it could to distribute the values, but had too many to parcel out, and was forced to send the right-most value ("baz") into the ether.
Note in the case above, we lost the last value. However it is actually possible to capture any such excess values and gather them into an array, using a related operator called the "splat" operator (which consists of an asterisk in front of the variable, as in *my_var
). You can do a number of useful things with this "splat" operator, but so as not to overload this answer too much, it's probably better to go elsewhere to look at examples of it in action. E.g., this blog post lists several variant uses.
One nice aspect of this parallel assignment facility is that you can swap values conveniently.
To swap values without parallel assignment, you might write something like this:
> a = 'foo'
> b = 'bar'
> temp = a # Introduce a temp variable
> a = b
> b = temp
> a
=> "bar"
> b
=> "foo"
But with parallel assignment, you can simply rely on Ruby to implicitly handle the swapping for you:
> a = 'foo'
> b = 'bar'
> b, a = a, b
> a
=> "bar"
> b
=> "foo"
Upvotes: 1
Reputation: 3891
What you're seeing is actually list expansion. Ruby can do the following:
a, b = 1, 2
This is essentially the same as:
a = 1
b = 2
I'll leave the rest for you to figure out.
Upvotes: 6