I'm not sure what exactly is going on with the code snippet below.
>> a, b = ["ho", "hey"]
=> ["ho", "hey"]
>> a
=> "ho"
>> b
=> "hey"
>> c, d = "foo", "bar"
=> ["foo", "bar"]
>> c
=> "foo"
>> d
=> "bar"
>> a, b = ["blerg"], ["baz"]
=> [["blerg"], ["baz"]]
>> a
=> ["blerg"]
>> b
=> ["baz"]
Why wouldn't line 1 return a => ["ho"]
?
So behind the scenes, what's the difference between these three assignments (a, b = ["ho", "hey"]
, c, d = "foo", "bar"
, a, b = ["blerg"], ["baz"]
)?
To update an element in the array, assign a new value to the element's index by using the assignment operator, just like you would with a regular variable.
In Ruby, there are several ways to retrieve the elements from the array. Ruby arrays provide a lot of different methods to access the array element. But the most used way is to use the index of an array.
We can use range operator with the slice method. In the first line we read elements from index 2 to 6, in the second line elements from 2 to 5. The slice method returns portions of the array, one or more elements of the array. It is possible to select a random value from an array.
Technically Ruby doesn't return two values. It can return one array which in turn gets assigned to two variables.
a, b = ["ho", "hey"]
a
is assigned the first element of the array, which is the string "ho". Nothing weird.
a, b = ["blerg"], ["baz"]
a, b = [["blerg"], ["baz"]]
These two are the same, as you can see by their return values. So a is assigned the first element, which is an array with one element: ["blerg"]
.
Similarly,
c, d = "foo", "bar"
Is the same as
c, d = ["foo", "bar"]
In Ruby, =
takes a list of variables on the left, and a list of expressions on the right. It assigns the the first variable to the value of the first expression, the second variable the value of the second expression, and so on. If there are more variables than expressions, the leftover variables get assigned the value nil
.
> a, b, c, d = "foo", 2+3, Array.new(2, 3), [:c, :d]
> a # => "foo"
> b # => 5
> c # => [3, 3]
> d # => [:c, :d]
> e # => nil
There are two exceptions:
Left side has only one variable, right side has multiple expressions
In this case, the above rule would say that the variable just gets set to the value of the first expression on the right. Instead, the variable gets set to the Array consisting of the values of the expression on the right. In the example below, we see a
gets the value [:b, :c]
, instead of just :b
:
> a = :b, :c
> a # => [:b, :c]
This is equivalent to:
> *a = :b , :c
> a # => [:b, :c]
The other exception:
The left side has multiple variables, the right side has only one expression and it's an Array
Again, the original rule would imply that the first variable gets set to that whole Array, and the rest of the variables would be nil. However, that Array effectively ends up getting replaced with the list of its elements, and then =
reverts to the "default" behaviour described in the beginning:
> a, b, c = [:d, [:e, :f]]
> a # => :d
> b # => [:e, :f]
> c # => nil
This is equivalent to a, b, c = *[:d, [:e, :f]]
, or just a, b, c = :d, [:e, :f]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With