In Ruby (1.9.3) why does this code not change the array values:
arr = ['a', 'b', 'c']
arr.each do |e|
e = 'new string'
end
This code never does anything with the array values. Why would it change them? It simply assigns a string to the local variable e
, which falls out of scope immediately, so the entire thing is a no-op.
While this code does change the hashes in item-b:
hashh = {
'item-a' => 1,
'item-b' => [
{'id'=>'a','name'=>'name-a'},
{'id'=>'b', 'name'=>'name-b'}
]
}
hashh['item-b'].each do |e|
e['name'] = 'new-name'
end
Hash#[]=
is a method which mutates the hash. Since you call a method which mutates the value (which is a hash), the value is mutated.
I know that I can use map on the array to change the values
map
does not change the values. It returns a new array. (Well, obviously, you can change the values in a map
, but that's not what it was designed for, and you shouldn't do it.)
by why does each allow me to change the hashes but not the array values?
each
doesn't do anything here. In the second case, you call a method which mutates the value, ergo, the value gets mutated. In the first case, you don't call a method which mutates the value; in fact, you don't call any method at all. Ergo, the value doesn't get mutated.