Matrix: Need help to understand this behavior

a=[1]
b=a # make matrix “b” equal matrix “a”, but expected 2
separated matrices
b[0]=2*b[0] # I want to change matrix “b” (and not matrix “a”)
p a # print matrix “a” and see the “issue”

The expected value in the matrix “a” should be 1, but instead it is 2.

Why ?

Thank you.
Marcio

On Sun, Aug 17, 2008 at 3:55 PM, Marcio B. [email protected]
wrote:

Thank you.
Marcio

Typical Ruby behavior.

In Ruby, variables reference objects rather than contain values.
Therefore, when you write b = a, b references the same object as a does.
Therefore, when you modify b, you modify a.
See the obejct_ids in your code:

$>cat mat.rb
#!/usr/bin/env ruby -wKU

a = [1]
b = a
puts a.object_id
puts b.object_id
b[0] = 2 * b[0]
p a
p b
$>ruby mat.rb
284610
284610
[2]
[2]
$>

See ? same objects.

To do what you want, you need to duplicate your array rather than just
assign it :
$>cat dup_mat.rb
#!/usr/bin/env ruby -wKU

a = [1]
b = a.dup
puts a.object_id
puts b.object_id
b[0] = 2 * b[0]
p a
p b
$>ruby dup_mat.rb
284540
284530
[1]
[2]
$>

Hope it helped.

Just to complement, as a contrast, the code below works as expected, or
in other words, the content of matrix “a” is not changed when you change
the content of matrix “b”.

b=[]
a=[1]
b[0]=a[0] # explicitly set a single element and not the entire
matrix
b[0]=2*b[0]
p a

Marcio

Marcio B. wrote:

a=[1]
b=a # make matrix “b” equal matrix “a”, but expected 2
separated matrices
b[0]=2*b[0] # I want to change matrix “b” (and not matrix “a”)
p a # print matrix “a” and see the “issue”

The expected value in the matrix “a” should be 1, but instead it is 2.

Why ?

Thank you.
Marcio

Thank you Zacek. I understand your point and that help very much.

Have a nice day !!
Marcio

Frantisek ZACEK wrote:

On Sun, Aug 17, 2008 at 3:55 PM, Marcio B. [email protected]
wrote:

Thank you.
Marcio

Typical Ruby behavior.

Hope it helped.

Zacek and all: how to duplicate a matrix that has elements that are also
matrix ?
For example:

a = [[1]]
b = a.dup
puts a.object_id
puts b.object_id
puts a[0].object_id # the same object
puts b[0].object_id # the same object
b[0][0] = 2 * b[0][0]
p a
p b

So, matrix “a” and “b” are different objects but each internal matrix
element continue to be the same object. Do I need to duplicate each one
?

Thank you
Marcio

On Sun, Aug 17, 2008 at 4:22 PM, Marcio B. [email protected]
wrote:

Marcio

Here you create explicitely two objects therefore : no problem whereas
on the first snippet, you only have one.

On Sun, Aug 17, 2008 at 4:53 PM, Marcio B. [email protected]
wrote:

b[0][0] = 2 * b[0][0]
Posted via http://www.ruby-forum.com/.

I don’t think there is a simple way to achieve that.
I would suggest:
a=[[1]]
b=a.dup.colllect { |e| e.dup }

I don’t think there is a simple way to achieve that.
I would suggest:
a=[[1]]
b=a.dup.colllect { |e| e.dup }

Ok.
So I need to create “my own” function to do that (just in case
a=[[[1]]])

Thank you

On Sun, Aug 17, 2008 at 9:53 AM, Marcio B. [email protected]
wrote:

b[0][0] = 2 * b[0][0]
p a
p b

So, matrix “a” and “b” are different objects but each internal matrix
element continue to be the same object. Do I need to duplicate each one
?

It’s a Matrix, right? (some of this stolen from a previous thread)…

require ‘matrix’
class Matrix
def []=(i, j, n)
@rows[i][j] = n
end
end

m = Matrix[[‘a’, ‘b’], [‘c’, ‘d’]]
k = m.clone
k[0, 0] = ‘e’
puts k.to_a
puts m.to_a

Todd

It’s a Matrix, right? (some of this stolen from a previous thread)…

require ‘matrix’
class Matrix
def []=(i, j, n)
@rows[i][j] = n
end
end

m = Matrix[[‘a’, ‘b’], [‘c’, ‘d’]]
k = m.clone
k[0, 0] = ‘e’
puts k.to_a
puts m.to_a

Todd

At first I was not considering to handle them using Matrix class (just
Array class) but thank you to call attention to this clone method of
Matrix.

Marcio