Can you make sense of this Array issue


#1

I want to have an array, say 5x5 with all nils unless set to something
else.
However, when I set m[0][0] to 0 … all 0 indices are set to zero…
Hmm…
never asked for that to be the case.
There’s some funky stuff going on here.

irb(main):001:0> n = 5
=> 5
irb(main):002:0> m = [[nil]*n]*n
=> [[nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil,
nil,
nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil]]
irb(main):003:0> m[0][0] = 0
=> 0
irb(main):004:0> m
=> [[0, nil, nil, nil, nil], [0, nil, nil, nil, nil], [0, nil, nil, nil,
nil], [0, nil, nil, nil, nil], [0, nil, nil, nil, nil]]

Any ideas?


#2

O I think I did figure this out. It seems the * operator just duplicates
the
pointers in some optimized fashion. If the nxn array is constructed by
setting each m[i][j] element everything works fine… I should have
thought
of that before.

irb(main):001:0> n = 5
=> 5
irb(main):002:0> m = []
=> []
irb(main):003:0> for i in 0…(n-1)
irb(main):004:1> m[i] ||= []
irb(main):005:1> for j in 0…(n-1)
irb(main):006:2> m[i][j] = nil
irb(main):007:2> end
irb(main):008:1> end
=> 0…4
irb(main):009:0> m
=> [[nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil,
nil,
nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil]]
irb(main):010:0> m[0][0] = 0
=> 0
irb(main):011:0> m
=> [[0, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil,
nil,
nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil]]


#3

In message
removed_email_address@domain.invalid, “Roland
Mai” writes:

I want to have an array, say 5x5 with all nils unless set to something else.
However, when I set m[0][0] to 0 … all 0 indices are set to zero… Hmm…
never asked for that to be the case.
There’s some funky stuff going on here.

irb(main):001:0> n = 5
=> 5
irb(main):002:0> m = [[nil]*n]*n

Nothing odd here, you’re making an array containing the SAME n-ary array
n times.

-s


#4

You might be interested in comparing:

Array.new(10, [])
and
Array.new(10) {[]}


#5

Here’s my interpretation so far.

Array.new(10, []) creates an array with [] being duplicated 10 times.
Basically, each [] is a mirror/pointer to the original [] object.

Array.new(10) {[]} creates the same array but the difference is that
each
time [] creates a different object unlike above where the new object was
merely a pointer.