[Q] Array.new - strange behavior

dear rubyists,

today i noticed a strange bahavior in Array.new while defining multi
dimentional arrays:

p "P1"
foo = Array.new(3,[0,0])
foo.each do |foo1|
p foo1.id
end

p "P2"
foo = Array.new
3.times {foo.push [0,0]}
foo.each do |foo1|
p foo1.id
end

produces:

"P1"
19645868
19645868
19645868
"P2"
19645760
19645748
19645736
Completed(0)

Is it intentional that the new method fills the array with just one
instance of [0,0]? In my sense this is a violation of the PoLS.

Thanks for any hints.

Eric.

dear rubyists,

today i noticed a strange bahavior in Array.new while defining multi
dimentional arrays:

p “P1”
foo = Array.new(3,[0,0])
foo.each do |foo1|
p foo1.id
end

I think I had a similar problem when I started with Ruby (coming from
the C/C++ environment)… the solution was what you had following…

p “P2”
foo = Array.new
3.times {foo.push [0,0]}
foo.each do |foo1|
p foo1.id
end

produces:

“P1”
19645868
19645868
19645868
“P2”
19645760
19645748
19645736
Completed(0)

Interestingly, I get different results:

irb(main):001:0> p “P1”
“P1”
=> nil
irb(main):002:0> foo = Array.new()
=>
irb(main):003:0> 3.times{
irb(main):004:1* foo << Array.new( 0, 0 )
irb(main):005:1> }
=> 3
irb(main):006:0> foo.each{ |i|
irb(main):007:1* p i.id
irb(main):008:1> }
20999324
20999312
20999300
=> [, , ]
irb(main):009:0> foo = Array.new()
=>
irb(main):010:0> 3.times{
irb(main):011:1* foo.push [0,0]
irb(main):012:1> }
=> 3
irb(main):013:0> foo.each{ |i| p i.id }
20964584
20964572
20964536
=> [[0, 0], [0, 0], [0, 0]]
irb(main):014:0>

···

On Tue, 11 May 2004 18:18:59 +0900, E.-R. Bruecklmeier unet01@radio-eriwan.de wrote:

Is it intentional that the new method fills the array with just one
instance of [0,0]? In my sense this is a violation of the PoLS.

Thanks for any hints.

Eric.

yes, it’s the normal behaviour.
If you want you can initialize an Array with a block, say:
Array.new(10) { rand }
The block gets executed for every element in the array, giving
different obvjects (or many copies of the same, in your case)

···

il Tue, 11 May 2004 11:15:34 +0200, “E.-R. Bruecklmeier” unet01@radio-eriwan.de ha scritto::

Is it intentional that the new method fills the array with just one
instance of [0,0]? In my sense this is a violation of the PoLS.

“E.-R. Bruecklmeier” unet01@radio-eriwan.de schrieb im Newsbeitrag
news:c7q5it$jc5$1@news.BelWue.DE

dear rubyists,

today i noticed a strange bahavior in Array.new while defining multi
dimentional arrays:

p “P1”
foo = Array.new(3,[0,0])
foo.each do |foo1|
p foo1.id
end

p “P2”
foo = Array.new
3.times {foo.push [0,0]}
foo.each do |foo1|
p foo1.id
end

produces:

“P1”
19645868
19645868
19645868
“P2”
19645760
19645748
19645736
Completed(0)

Is it intentional that the new method fills the array with just one
instance of [0,0]? In my sense this is a violation of the PoLS.

Well, I’d say no, if you aware of how Ruby deals with instances and
variables. All variables hold references - there is no distinction
between pass by value and pass by reference as it is in C++. Then you’ll
see that a single instance is handed over to the constructor in your first
example. That instance is used for each array element, which is fine for
immutable classes (integers for example). If you need different
instances, you’ll need the block form as shown by you or even better the
other one:

foo = Array.new( 3 ) {[0,0]}

irb(main):002:0> foo = Array.new( 3 ) {[0,0]}
=> [[0, 0], [0, 0], [0, 0]]
irb(main):003:0> foo.each {|o| puts o.id}
135011840
135011828
135011816
=> [[0, 0], [0, 0], [0, 0]]

Regards

robert