Freeze and hash

Hello

irb(main):069:0* a = Hash.new([])
=> {}
irb(main):070:0> a[1] << “X”
=> [“X”]
irb(main):071:0> a.freeze
=> {}
irb(main):072:0> a.frozen?
=> true
irb(main):073:0> b = a.dup
=> {}
irb(main):074:0> b.frozen?
=> false
irb(main):075:0> b.default
=> [“X”]
irb(main):076:0> b[11] << “Y”
=> [“X”, “Y”]
irb(main):077:0> b.default
=> [“X”, “Y”]
irb(main):078:0> a.default
=> [“X”, “Y”]
irb(main):079:0> a.frozen?
=> true
irb(main):080:0> b.frozen?

as one can see a.default is a flat copy
so a is modified though it’s frozen

what is the usual idom to get deep copy?

Regards, Daniel

Schüle Daniel wrote:

irb(main):073:0> b = a.dup
=> [“X”, “Y”]
irb(main):079:0> a.frozen?
=> true
irb(main):080:0> b.frozen?

as one can see a.default is a flat copy
so a is modified though it’s frozen

what is the usual idom to get deep copy?

Regards, Daniel

Try

a = Hash.new { [] }

When a default value is needed the proc is run and its return value is
used.
See ri Hash.new for more info.

-Charlie

Schüle Daniel wrote:

irb(main):073:0> b = a.dup
=> [“X”, “Y”]

Freezing the hash doesn’t freeze the array that is its default value
(shared with b). See yesterday’s thread “Strange behavior” about what’s
going on here.

Regarding the deep copy, the usual idiom is Marshal.dump/Marshal.load.