How does the block form of Array#new work given “Array.new(10) { |e| e = e * 2 }”?

前端 未结 2 1329
夕颜
夕颜 2021-01-26 05:50

I am having trouble understanding the part inside the curly braces.

Array.new(10) { |e| e = e * 2 }
# => [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]   
2条回答
  •  情深已故
    2021-01-26 06:32

    What Your Code Does

    nums = Array.new(10) { |e| e = e * 2 }
    

    Break it down step by step in IRB or Pry to see what your code is really doing. For example:

    1. Array.new(10) creates an array with 10 elements.
    2. Array.new(10) { |e| puts e } prints the index of each element, which will be 0..9.
    3. The construct { |e| e = e * 2 }, or more idiomatically { |e| e * 2 }, is a Ruby block that multiplies the index of each element passed to the block variable e by 2.
    4. nums = Array.new(10) { |e| e = e * 2 } takes the result of the block and stores it in the variable nums.

    Note that this stored array is created via the block form of Array#new, which says that when using the block form of the constructor:

    [A]n array of the given size is created. Each element in this array is created by passing the element’s index to the given block and storing the return value.

    The example in the original post is certainly valid Ruby code, but not particularly clear. The same result can be had with more explicit code, such as the example below.

    One of Many Clearer Alternatives

    There's always more than one way to do things, especially in Ruby. If you want to be more explicit about what your code is doing, use a less "magical" construct. For example, your code is roughly equivalent to:

    num_array = 0.upto(9).map { |int| int * 2 }
    #=> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    

提交回复
热议问题