[Q] Array.new - strange behavior

E

E.-R. Bruecklmeier

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.
 
G

gabriele renzi

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.

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)
 
R

Robert Klemme

E.-R. Bruecklmeier said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,371
Latest member
Brkaa

Latest Threads

Top