Ruby array initialization

I need to know the technical difference between these two statements and why it behaves like this:

arr = Array.new(3, "abc")
=> ["abc","abc","abc"]
arr.last.upcase!
=> "ABC"
arr
=>["ABC","ABC","ABC"]     # which is **not** what I excepted

      

On the other hand:

arr = Array.new(3){"abc"}
=> ["abc","abc","abc"]
arr.last.upcase!
=>"ABC"
arr
=> ["abc","abc","ABC"]     # which is what I excepted

      

+3


source to share


1 answer


Arguments are always evaluated before the method is called, whereas the block is only evaluated at the time of the method call at the point controlled by the method (if it is ever evaluated).

In the first example, the argument "abc"

is evaluated once before calling the method new

. The evaluated object is passed to the method new

. The exact same object is used in all three elements of the created array. Changing one means changing all of them.



In your second example, the block {"abc"}

is evaluated every time a new element is created for the array. The three elements in the generated array are different objects.

+8


source







All Articles