Dup a Constant

I have a constant in my helper : MYCONSTANT = { :opt => { :title => "abcdef" } }

In my view : <% joke = PeopleHelpers::MYCONSTANT.dup joke[:opt][:title] = nil #if i debug there, PeopleHelpers::MYCONSTANT = {:opt => {:title => nil}} %>

I can't understand this behaviour and how fix it ? Is it a bug ?

In fact the previous example doesn't change the value of PeopleHelpers::MYCONSTANT

but if I do : <% joke = PeopleHelpers::MYCONSTANT.dup joke[:opt][:title].sub!('a','b') #if i debug there, PeopleHelpers::MYCONSTANT = {:opt => {:title => bbcdef}} %>

the value changed.. why ?

I have a constant in my helper : MYCONSTANT = { :opt => { :title => "abcdef" } }

In my view : <% joke = PeopleHelpers::MYCONSTANT.dup joke[:opt][:title] = nil #if i debug there, PeopleHelpers::MYCONSTANT = {:opt => {:title => nil}} %>

I can't understand this behaviour and how fix it ? Is it a bug ?

No, #dup and #clone typically make shallow copies.

orig = { :opt => { :title => 'hello' } }

=> {:opt=>{:title=>"hello"}}

dup = orig.dup

=> {:opt=>{:title=>"hello"}}

dup[:opt][:title]

=> "hello"

dup[:opt][:title] = nil

=> nil

dup

=> {:opt=>{:title=>nil}}

orig

=> {:opt=>{:title=>nil}}

orig = { :opt => { :title => 'hello' } }

=> {:opt=>{:title=>"hello"}}

clone = orig.clone

=> {:opt=>{:title=>"hello"}}

clone[:opt][:title]

=> "hello"

clone[:opt][:title] = nil

=> nil

clone

=> {:opt=>{:title=>nil}}

orig

=> {:opt=>{:title=>nil}}

If you want a "deep" copy, usually you Marshal and un-Marshal:

orig = { :opt => { :title => 'hello' } }

=> {:opt=>{:title=>"hello"}}

marshaled = Marshal.load(Marshal.dump(orig))

=> {:opt=>{:title=>"hello"}}

marshaled[:opt][:title]

=> "hello"

marshaled[:opt][:title] = nil

=> nil

marshaled

=> {:opt=>{:title=>nil}}

orig

=> {:opt=>{:title=>"hello"}}

-Rob

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com

My understanding is that dup makes a copy of the hash contents, but since the contents are themselves references rather than simple objects you end up with a new hash containing references to the same objects, which can then be modified as you have noted (even though they are notionally constant).

Colin

Thank you very much for your explanations :slight_smile:

adrien