Ruby bug or not?

Using 1.8.4 on OSX.

class CopyTest
attr_accessor :one
end

a = CopyTest.new
a.one = [1,2,3,4]
b = a.clone
a.freeze

b.one.each_with_index do |item,index|
b.one.delete_at(index) if item == 2
end

this is supposed to delete the first item in the array that matches

instead of all matching items

b.one #=> [1,3,4]

No surprises so far…

a.one #=> [1,3,4]

Now that is weird.

a #=> #<CopyTest:0x35a4ec @one=[1, 3, 4]>
b #=> #<CopyTest:0x348698 @one=[1, 3, 4]>

Not the same object, so why does changing one affect the other?

if you do this…

a.one = [1,2,3,4]
b=a.clone
b.one = [4,3,2,1]

then things work normally
a.one #=> [1,2,3,4]
b.one #=> [4,3,2,1]

I suspect there is a bug in the ‘delete_at’ function or in the way that
objects are cloned that causes them to refer to the same array in some
cases.

Thoughts?

a.one = [1,2,3,4] #=> TypeError: can’t modify frozen object

Strange, I also managed to change a frozen object this way.

_Kevin
www.sciwerks.com

On Aug 15, 2006, at 11:18 AM, Kevin O. wrote:

b = a.clone

That’s not a deep copy:

class CopyTest
attr_accessor :one
end
=> nil

?> a = CopyTest.new
=> #CopyTest:0x337898

a.one = [1,2,3,4]
=> [1, 2, 3, 4]

b = a.clone
=> #<CopyTest:0x32fc4c @one=[1, 2, 3, 4]>

a.one.object_id
=> 1673774

b.one.object_id
=> 1673774

James Edward G. II

“K” == Kevin O. [email protected] writes:

Write it like this

K> class CopyTest
K> attr_accessor :one

def initialize_copy(obj)
   self.one = obj.one.clone
end

K> end

Guy Decoux

On Wed, Aug 16, 2006 at 01:18:21AM +0900, Kevin O. wrote:

a.one #=> [1,3,4]

Now that is weird.

a #=> #<CopyTest:0x35a4ec @one=[1, 3, 4]>
b #=> #<CopyTest:0x348698 @one=[1, 3, 4]>

Not the same object, so why does changing one affect the other?

a.instance_variable_get(:@one).object_id
=> 177242
b.instance_variable_get(:@one).object_id
=> 177242

The containing instances aren’t the same object but they are composed of
the
same array object.

Object#clone copies the instance variables of the object being cloned.

marcel

On Wednesday, August 16, 2006, at 1:29 AM, Marcel Molina Jr. wrote:

a.freeze
No surprises so far…
a.instance_variable_get(:@one).object_id
marcel

Marcel Molina Jr. [email protected]

Yeah, one of those things you figure out right after you post it.

It does concern me that after freezing a, I could modify a.one through
b.

I can see that one may not want to have ‘freeze’ be called recursively
on all instance variables, but it sure did throw me off in this case.

-Kevin

_Kevin
www.sciwerks.com