ruby dup unexpected behaviour

D

David Maciejak

Hi,

I got no answer on ubuntu entry at
https://bugs.launchpad.net/ubuntu/+source/ruby1.8/+bug/384265
so I resend it here. Does someone have any clues on this ?

Thanks,
david


--------------------------------------------------------------------------------------

Hi,

got some strange result in ruby1.8 (1.8.7.72-3) on jaunty (up to date).
Don't know if I use correctly dup function but my duped hash is
modified even if i call the freeze method. Below the quick and dirty
test case showing that @c member of the class Global is modified


#!/usr/bin/ruby

class Testme
attr_accessor :value
def initialize(val)
@value=val
end
def Testme::bou(val)
$a["b"].value=val
end
def to_str()
print @value,"\n"
end
end

class Global

def initialize
@c=nil
end

def go()
@c=$a.dup
@c.freeze
#print value before the changes
to_str()
end
def to_str()
print @c,"\n"
end

end

$a=Hash.new
$a["a"]=Testme.new(1)
$a["b"]=Testme.new(2)

main=Global.new
main.go()
Testme::bou(3)
#print value after the changes
main.to_str()
 
B

Brian Candler

David said:
I got no answer on ubuntu entry at
https://bugs.launchpad.net/ubuntu/+source/ruby1.8/+bug/384265
so I resend it here. Does someone have any clues on this ?

dup is a "shallow" copy. For a Hash, you'll get a new Hash but with the
keys and values pointing to the same objects.
h1 = {1=>"one", 2=>"two"} => {1=>"one", 2=>"two"}
h2 = h1.dup => {1=>"one", 2=>"two"}
h1.object_id => -605621648
h2.object_id => -605633988 #<< the hashes are different objects
h1[1].object_id => -605621708
h2[1].object_id => -605621708 #<< the values are the same object

If you want a deep copy, you have to do it yourself.

Similarly, if you freeze a Hash, you are just freezing the Hash itself,
not all the objects it points to.
h1 => {1=>"one", 2=>"two"}
h1.freeze => {1=>"one", 2=>"two"}
h1[2] << "xxx" => "twoxxx"
h1
=> {1=>"one", 2=>"twoxxx"}

If you want a "deep freeze" then you'll have to do it yourself.

Your test code looks rather more convoluted than it needs to be, so you
should be able to boil it down to a two or three line case which shows
you what's happening.

However I suggest you close the Ubuntu ticket though as 'invalid'

Regards,

Brian.
 
D

David Maciejak

Thanks for the details, in the end as you said I did the deep copy
myself. I will close the ubuntu entry.

david

David said:
I got no answer on ubuntu entry at
https://bugs.launchpad.net/ubuntu/+source/ruby1.8/+bug/384265
so I resend it here. Does someone have any clues on this ?

dup is a "shallow" copy. For a Hash, you'll get a new Hash but with the
keys and values pointing to the same objects.
h1 =3D {1=3D>"one", 2=3D>"two"} =3D> {1=3D>"one", 2=3D>"two"}
h2 =3D h1.dup =3D> {1=3D>"one", 2=3D>"two"}
h1.object_id =3D> -605621648
h2.object_id =3D> -605633988 =A0 =A0 =A0 =A0 =A0 #<< the hashes are different objects
h1[1].object_id =3D> -605621708
h2[1].object_id =3D> -605621708 =A0 =A0 =A0 =A0 =A0 #<< the values are the same object

If you want a deep copy, you have to do it yourself.

Similarly, if you freeze a Hash, you are just freezing the Hash itself,
not all the objects it points to.
h1 =3D> {1=3D>"one", 2=3D>"two"}
h1.freeze =3D> {1=3D>"one", 2=3D>"two"}
h1[2] << "xxx" =3D> "twoxxx"
h1
=3D> {1=3D>"one", 2=3D>"twoxxx"}

If you want a "deep freeze" then you'll have to do it yourself.

Your test code looks rather more convoluted than it needs to be, so you
should be able to boil it down to a two or three line case which shows
you what's happening.

However I suggest you close the Ubuntu ticket though as 'invalid'

Regards,

Brian.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top