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

Why does 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:

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"]]

I know I'm not using
correctly, 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 three different arrays, but modifying the same array in the map block.

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

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

As a side note, you could use this code, which is more obvious than the code above, for the output you desire:

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