From: Robert Klemme Date: 2013-04-17T19:00:36+09:00 Subject: Re: Delete method also modifies the original variable --14dae9399b0393e81e04da8b8e04 Content-Type: text/plain; charset=ISO-8859-1 On Wed, Apr 17, 2013 at 7:34 AM, Tony Arcieri wrote: > On Tue, Apr 16, 2013 at 9:10 PM, Matthew Kerwin wrote: > >> There is no general-form solution to creating a deep-copy of a >> datastructure in ruby. > > > A (suboptimal) solution for deep copies in Ruby is to use Marshal. > > It sure would be nice if Ruby had some sort of analogue for structured > cloning. > What exactly do you mean by "structured cloning"? Do you have ideas how that should work? Sketch: # untested class CloneContext def initialize @store = {} end def deep_clone(*objs) objs.map do |o| copy_one(o) rescue o end end private def copy_one(obj) @store.fetch obj.object_id do |oid| (@store[oid] = obj.class.allocate).tap do |copy| # add specific handling for Array, String etc. or delegate to #clone method of obj obj.instance_variables.each do |var| copy.instance_variable_set(deep_clone(obj.instance_variable_get(var))) end end end end end Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/ --14dae9399b0393e81e04da8b8e04 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable



On Wed, Apr 17, 2013 at 7:34 AM, Tony Arcieri <= ;tony.arcieri@g= mail.com> wrote:
On Tue, Apr 16, 2013 at= 9:10 PM, Matthew Kerwin <lists@ruby-forum.com> wrote:
There is no general-form solution to creating a deep-copy of a
datastructure in ruby.

A (suboptimal)= solution for deep copies in Ruby is to use Marshal.

It sure would be nice if Ruby had some sort of analogue for structured c= loning.

What exactly do you mean by "= structured cloning"? =A0Do you have ideas how that should work?
<= div class=3D"gmail_extra">
Sketch= :=A0

# untested

class CloneContext
= =A0 def initialize
=A0 =A0 @store =3D {}
=A0 end

<= div class=3D"gmail_extra" style>=A0 def deep_clone(*objs)
=A0 =A0 objs.map do |o|
=A0 =A0 =A0 c= opy_one(o) rescue o
=A0 =A0 end
=
=A0 end

private
=A0 def copy_one(obj)
=A0 =A0 @store.fetch obj.object_id do |oid|<= /div>
=A0 =A0 =A0 (@store[oid] =3D obj.clas= s.allocate).tap do |copy|
=A0 =A0 =A0 =A0 # add specific handling fo= r Array, String etc. or delegate to #clone method of obj
=A0 =A0 =A0 =A0 obj.instance_variables.each do |var|
=A0 =A0 =A0 =A0 =A0 copy.instance_variable_set(deep_clone(obj.instance_vari= able_get(var)))
=A0 =A0 =A0 =A0 end
=A0 =A0 =A0 end
= =A0 =A0 end
=A0 end
end
=
Kind regards

robert


--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/ --14dae9399b0393e81e04da8b8e04--