Andrew Kim Andrew Kim - 3 months ago 5x
Ruby Question

Why does ruby map enumerable return value not return expected value

I'm pretty familiar with the ruby enumerable module. Or at least so I thought. Take the following code snippet though:

names = [ "Donald", "Daisy", "Daffy" ]

new_empty_array = []

new_names_array = do |name|
new_empty_array << name

puts new_names_array.inspect
# prints [["Donald", "Daisy", "Daffy"], ["Donald", "Daisy", "Daffy"], ["Donald", "Daisy", "Daffy"]]

Now, I know I'm not using map correctly here, but I was teaching a lesson on ruby enumerables and came across this example when a student was testing
out. The return value of the shovel(
) operator is the array after an element has been added. Shouldn't the result instead be:

[["Donald"], ["Donald", "Daisy"], ["Donald", "Daisy", "Daffy"]]

It seems that the entire loop processes and the final return value of the shovel operator is processed..what gives?


The result of map, in your case, is an array which consists of references to same array new_empty_array multiple times. You are not creating 3 different arrays, but modifying same array in the body of map.

To get the output you are expecting, you need to do:

new_names_array = do |name|
  (new_empty_array << name).dup

On a side note, you could use below code which is more intention-revealing than above code for the output you desire:

(1..first_names.size).map do |num|
#=> [["Donald"], ["Donald", "Daisy"], ["Donald", "Daisy", "Daffy"]]