Forum: Ruby Array#shift weird problem

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
32907e8553c67c6a04980b5e81ecda0e?d=identicon&s=25 Hamza Haiken (tenchi)
on 2008-12-05 10:26
Hi

Can someone explain to me why is this happening ?

>> matrix1 = ["One","Two","Three"]
=> ["One", "Two", "Three"]
>> matrix2 = matrix1
=> ["One", "Two", "Three"]
>> matrix2.shift
=> "One"
>> matrix2
=> ["Two", "Three"]
>> matrix1
=> ["Two", "Three"]

According to my logic, when I do matrix2.shift, it should have nothing
to do with matrix1. Why's this one shifted as well ?
C40020a47c6b625af6422b5b1302abaf?d=identicon&s=25 Stefano Crocco (crocco)
on 2008-12-05 10:41
(Received via mailing list)
Alle Friday 05 December 2008, Hamza Haiken ha scritto:
> => ["One", "Two", "Three"]
>
> => ["Two", "Three"]
>
> According to my logic, when I do matrix2.shift, it should have nothing
> to do with matrix1. Why's this one shifted as well ?

Because matrix1 and matrix2 are only different names used to refer to
the same
thing, as you can see by checking the values returned by
matrix1.object_id and
matrix2.object_id. If you want the two variables to contain different
objects,
you need to write

matrix2 = matrix1.dup

This will set the contents of matrix2 to a duplicate of matrix1, so that
changing one won't change the other. Note, however, that this is only a
shallow copy, that is: the array itself is duplicated, but its contents
aren't. This means that any method which changes one of the contained
strings
in-place will affect both array. For example:

matrix2 = matrix1.dup
matrix1[0].sub!('O','o')
p matrix1
#=> ["one", "Two", "Three"]
p matrix2
#=> ["one", "Two", "Three"]

If you also need to be sure that the arrays contain different objects,
you
need to do a deep copy, which can be achieved using marshal:

matrix2 = Marshal.load(Marshal.dump(matrix1))

I hope this helps

Stefano
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2008-12-05 10:42
(Received via mailing list)
From: Hamza Haiken [mailto:tenkage@gmail.com]
# Can someone explain to me why is this happening ?

here matrix1 holds a ptr/reference to the array object

# >> matrix1 = ["One","Two","Three"]
# => ["One", "Two", "Three"]

here the reference is also copied to matrix2

# >> matrix2 = matrix1
# => ["One", "Two", "Three"]
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2008-12-05 10:47
(Received via mailing list)
On Fri, Dec 5, 2008 at 10:20 AM, Hamza Haiken <tenkage@gmail.com> wrote:
> Hi
>
> Can someone explain to me why is this happening ?
x = [42] makes x refer to the ArrayObject
y = x makes y refer to the *same* object, see for yourself
irb(main):001:0> x=[42]
=> [42]
irb(main):002:0> p x.object_id
77740410
=> 77740410
irb(main):003:0> y = x
=> [42]
irb(main):004:0> p y.object_id
77740410
=> 77740410

Now if you do this
irb(main):005:0> x << 42
=> [42, 42]

guess what y will refer to, still the same object, that happens to
have been altered

irb(main):006:0> y
=> [42, 42]

If you want y to refer to a different object you can do this
irb(main):001:0> x = [42]
=> [42]
irb(main):002:0> y = x.dup
=> [42]
irb(main):003:0> p [x.object_id, y.object_id]
[77455250, 77432630]
=> [77455250, 77432630]
irb(main):004:0> x << 42
=> [42, 42]
irb(main):005:0> p [x, y]
[[42, 42], [42]]
=> [[42, 42], [42]]

HTH
R.


--
Ne baisse jamais la tête, tu ne verrais plus les étoiles.

Robert Dober ;)
This topic is locked and can not be replied to.