Clone nested table

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Clone nested table

Tim Royal
Hi, I've been using Lua for an application I'm developing, and I have a
question about copying a nested table structure.

I have a system using templates. The application users will take an
existing table, and clone it to create a copy which they then can tweak.

Example:

Template

Pet = 
{
	Location={ Type="Pound", Region="Southwest" },
	Name="",
	Commands={	Fetch, Grovel, Growl }
}

User 

Monkey = 
{
	From=Pet,
	Name="MonkeySee",
	SpecialActions={	Warble, Swoon	},
	Move=function()
}

What I want to do is make a copy of the Pet template, and have Monkey
inherit the *copy* of Pet.

I have been able to copy root level values, but nested tables are not
copied, just the references. The problem above is if I iterate through
the Pet table and copy everything, if I change a value in the nested
tables, it changes it for the underlying Pet table because both Pet and
Monkey point to the same nested table.

Is there any facility that will let me make an independent copy of a
table and all its nested tables (yes, I understand the circular
reference problem that could occur, so I'll need to be careful).

Thanks for any insight!
Tim

Reply | Threaded
Open this post in threaded view
|

Re: Clone nested table

Luiz Henrique de Figueiredo
>I have a system using templates. The application users will take an
>existing table, and clone it to create a copy which they then can tweak.

Instead of cloning a table A into a table B, why not create an empty table B
and set the __index metamethod of B to be A? With this setup, reading from B
reads from A, but writing to B writes to B, not to A. To handle tables inside A,
the __index metamethod would have to set the same scheme for these tables.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: Clone nested table

Eric Tetz-2
In reply to this post by Tim Royal
--- "Tim Royal (ArtSource)" <[hidden email]> wrote:
> Is there any facility that will let me make an independent copy of a
> table and all its nested tables (yes, I understand the circular
> reference problem that could occur, so I'll need to be careful).

You just write your own. Here's the basic idea (I'm sure users here have more sophisticated
version):

function deep_copy (table)
  t = {}
  for k,v in table do
    if type(v) == 'table'
      v = deep_copy(v)
    end
    t[k] = v
  end
  return t
end


__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

Reply | Threaded
Open this post in threaded view
|

Re: Clone nested table

Mark Hamburg-4
In reply to this post by Luiz Henrique de Figueiredo
The __index approach is clever and a great solution for some cases, but it
doesn't handle everything where you want to copy.

That suffers from the problem that as long as B is around A stays around. If
A references a large structure via an entry hidden by B that structure won't
get collected even though no code will ever get to it.

While deepcopy is a much more complicated problem, I really wish there were
a copy operation with a standard implementation for the various types
(including doing nothing for strings since they are immutable) and metatable
support for overriding it. Yes, one can write this, but it could probably be
written much efficiently in something that was intimate with the
implementation data structures.

Mark

on 6/17/03 10:07 AM, Luiz Henrique de Figueiredo at [hidden email]
wrote:

>> I have a system using templates. The application users will take an
>> existing table, and clone it to create a copy which they then can tweak.
> 
> Instead of cloning a table A into a table B, why not create an empty table B
> and set the __index metamethod of B to be A? With this setup, reading from B
> reads from A, but writing to B writes to B, not to A. To handle tables inside
> A,
> the __index metamethod would have to set the same scheme for these tables.
> --lhf
>