Why does array.each behavior depend on Array.new syntax?

后端 未结 3 433
遇见更好的自我
遇见更好的自我 2020-12-11 05:13

I\'m using Ruby 1.9.2-p290 and found:

a = Array.new(2, []).each {|i| i.push(\"a\")}    
=> [[\"a\", \"a\"], [\"a\", \"a\"]]

Which is not

3条回答
  •  悲哀的现实
    2020-12-11 06:05

    In the first case you're using a single instance of an Array as a default for the elements of the main Array:

    a = Array.new(2, []).each {|i| i.push("a")}
    

    The second argument is simply recycled, so the push is applied to the same instance twice. You've only created one instance here, the one being supplied as an argument, so it gets used over and over.

    The second method is the correct way to do this:

    b = Array.new(2) {Array.new}.each {|i| i.push("b")
    

    This deliberately creates a new instance of an Array for each position in the main Array. The important difference here is the use of the block { ... } which executes once for each position in the new Array. A short-form version of this would be:

    b = Array.new(2) { [ ] }.each {|i| i.push("b")
    

提交回复
热议问题