[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Ruby bug or not?

Stefan Lang

8/15/2006 4:18:00 PM

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
--
Posted with http://De.... Sign up and save your mailbox.

4 Answers

James Gray

8/15/2006 4:27:00 PM

0

On Aug 15, 2006, at 11:18 AM, Kevin Olbrich 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 Gray II

ts

8/15/2006 4:28:00 PM

0

>>>>> "K" == Kevin Olbrich <devlists-ruby-talk@devlists.com> 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

Marcel Molina Jr.

8/15/2006 4:29:00 PM

0

On Wed, Aug 16, 2006 at 01:18:21AM +0900, Kevin Olbrich wrote:
> 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?

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
--
Marcel Molina Jr. <marcel@vernix.org>

Stefan Lang

8/15/2006 4:50:00 PM

0


On Wednesday, August 16, 2006, at 1:29 AM, Marcel Molina Jr. wrote:
>On Wed, Aug 16, 2006 at 01:18:21AM +0900, Kevin Olbrich wrote:
>> 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?
>
>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
>--
>Marcel Molina Jr. <marcel@vernix.org>
>

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

--
Posted with http://De.... Sign up and save your mailbox.