Mr. Kennedy Mr. Kennedy - 2 months ago 9
Ruby Question

Array.each do vs Array do - what is the difference?

I am at a loss to explain the result of evaluating the second code block (not using

).

Array.new(3).each do |i|; p i; end
# nil
# nil
# nil
#=> [nil, nil, nil]

Array.new(3) do |i|; p i; end
# 0
# 1
# 2
#=> [0, 1, 2] # <-- ???


I understand that:


  1. Array.new(#)
    invokes an Array with the corresponding # of
    nil
    values, and

  2. The call to the
    .each
    method with
    do |i|
    iterates over (enumerates?) each index value (=nil),

  3. p
    prints that value, and

  4. the code block ends.



I am confused as to how removing the
.each
method call results in the
Array.new
indexes getting assigned values.

Of note, an error is generated with the same
do
block after an explicitly declared array of nil values (if I am describing it correctly?)

[nil, nil, nil].each do |i|; p i; end
# nil
# nil
# nil
#=> [nil, nil, nil]

[nil, nil, nil] do |i|; p i; end
# SyntaxError: (irb):4: syntax error, unexpected keyword_do_block, expecting end-of-input
# [nil, nil, nil] do |i|; p i; end
# ^
# from C:/Ruby22/bin/irb:11:in `<main>'


I am assuming the
do
code block start paired with
Array.new
is making some kind of a difference. Any explanation of what is going on here would be very helpful. Thank you.

Answer

Array.new(3).each { ... } creates a new array with the size 3 and calls each on that array.

Whereas Array.new(3) { ... } creates an array of the size 3 and sends the block as a second argument to the new method. When you call new with a block then the return value of the block is used to initialize the array.

See the docs about Array#new

Comments