ruby dup unexpected behaviour

Bug #384265 reported by DavidM
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
ruby1.8 (Ubuntu)
Invalid
Undecided
Unassigned

Bug Description

Binary package hint: ruby1.8

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

Regards,
david

#!/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()

Revision history for this message
DavidM (david-maciejak) wrote :

got the answer from ruby list:

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.

Changed in ruby1.8 (Ubuntu):
status: New → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.