Create a new table based on an already existed table (through Lua or C API)?

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

Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
How to create a new table based on an already existed table (through
Lua or C API)?

This code snippet seems impossible to achieve this goal:

foo = {};
foo.a = 1;
foo.b = 2;

new = foo;
print(new, foo)  --they both point to the same table!

new.a = new.a+1;  --the value of foo.a has been modified too.
                              --I hope the table named `new` to be a
table which is independent from the table named `foo`.
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
This code snippet works, but it seems a little complicated indeed.
foo = {};
foo.a = 1;
foo.b = 2

tab={}
for k,v in pairs(foo) do
tab[k] = v
end

On Thu, Jan 21, 2021 at 11:25 AM 孙世龙 sunshilong <[hidden email]> wrote:

>
> How to create a new table based on an already existed table (through
> Lua or C API)?
>
> This code snippet seems impossible to achieve this goal:
>
> foo = {};
> foo.a = 1;
> foo.b = 2;
>
> new = foo;
> print(new, foo)  --they both point to the same table!
>
> new.a = new.a+1;  --the value of foo.a has been modified too.
>                               --I hope the table named `new` to be a
> table which is independent from the table named `foo`.
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

Scott Morgan
In reply to this post by 孙世龙 sunshilong
On 21/01/2021 03:25, 孙世龙 sunshilong wrote:
> How to create a new table based on an already existed table (through
> Lua or C API)?

If you know C, it helps to think of table values like they are pointers.
You don't copy the contents of a table, just the pointer to it.

What you want is a table copy (or clone) function, but you have two
choices on how to implement that; a shallow copy, or a deep copy.

Shallow copy just copies the first level of values in the source table.

Deep copy goes through any tables within the source table and copies
them too.

There is also a question about how to handle the the table's metatable
data (and in a deep copy, any sub-table's metatable)

As you can see, there's a lot of possible ways to do this, as well as
potential issues, such as if there are recursive tables (tables that
link to themselves). So the Lua team don't provide a copy operator or
function as they can't know what people need.

It is easy to write simple table copy functions that match your
requirements:
http://lua-users.org/wiki/CopyTable

Scott
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
Thank you for your detailed explanation.

The assignment operator does almost the same thing both in Lua and
Python whereas Python provides deepcopy() to do the aforementioned
deep copy.

>As you can see, there's a lot of possible ways to do this, as well as
>potential issues, such as if there are recursive tables (tables that

^^^^^^^^^^^^^^^^^^^^^^^^^^^
>link to themselves).
  ^^^^^^^^^^^^^^^^^
Could you give me a example(i.e recursive tables). I could not find much
information about it on Google(keyword: Lua recursive tables).

tab = {};
tab ={tab};
I don't think `tab` is a  recursive table indeed.

Thank you for your attention to my question.

On Thu, Jan 21, 2021 at 5:51 PM Scott Morgan <[hidden email]> wrote:

>
> On 21/01/2021 03:25, 孙世龙 sunshilong wrote:
> > How to create a new table based on an already existed table (through
> > Lua or C API)?
>
> If you know C, it helps to think of table values like they are pointers.
> You don't copy the contents of a table, just the pointer to it.
>
> What you want is a table copy (or clone) function, but you have two
> choices on how to implement that; a shallow copy, or a deep copy.
>
> Shallow copy just copies the first level of values in the source table.
>
> Deep copy goes through any tables within the source table and copies
> them too.
>
> There is also a question about how to handle the the table's metatable
> data (and in a deep copy, any sub-table's metatable)
>
> As you can see, there's a lot of possible ways to do this, as well as
> potential issues, such as if there are recursive tables (tables that
> link to themselves). So the Lua team don't provide a copy operator or
> function as they can't know what people need.
>
> It is easy to write simple table copy functions that match your
> requirements:
> http://lua-users.org/wiki/CopyTable
>
> Scott
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

Sudipto Mallick
Example:

        local t = {}
        t.t = t
        assert((t == t.t) and (t.t == t.t.t) and (t.t.t == t.t.t.t))
-- and so on

You remember _G, don't you?

        assert(_G['_G'] == _G)

--Sudipto Mallick
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
I see. Thank you.
I remembered it(i.e _G['_G' == _G]).

Where and when should I use the recursive tables?
I think _G is a good answer to this question. :) Am I missing something?

More importantly, how to find out the table is a  recursive table or
not through C API?
I think it's a difficult since I could not acquire the name which
passes to registered C function.

For example, I register int foo_func(struct lua_State* L) to Lua
through lua_register().
I could not know the argument passed to foo_func() is a recursive
table or not when encountering `foo_func(_G)` in Lua script.

On Thu, Jan 21, 2021 at 7:30 PM Sudipto Mallick <[hidden email]> wrote:

>
> Example:
>
>         local t = {}
>         t.t = t
>         assert((t == t.t) and (t.t == t.t.t) and (t.t.t == t.t.t.t))
> -- and so on
>
> You remember _G, don't you?
>
>         assert(_G['_G'] == _G)
>
> --Sudipto Mallick
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
>I think it's a difficult since I could not acquire the name which
>passes to registered C function.
It seems that I find a solution just now.

Comparing the pointer of the table (the one passed to foo_func) with
the `value`(which is contained in the aforementioned table) pointed
to.

On Thu, Jan 21, 2021 at 7:51 PM 孙世龙 sunshilong <[hidden email]> wrote:

>
> I see. Thank you.
> I remembered it(i.e _G['_G' == _G]).
>
> Where and when should I use the recursive tables?
> I think _G is a good answer to this question. :) Am I missing something?
>
> More importantly, how to find out the table is a  recursive table or
> not through C API?
> I think it's a difficult since I could not acquire the name which
> passes to registered C function.
>
> For example, I register int foo_func(struct lua_State* L) to Lua
> through lua_register().
> I could not know the argument passed to foo_func() is a recursive
> table or not when encountering `foo_func(_G)` in Lua script.
>
> On Thu, Jan 21, 2021 at 7:30 PM Sudipto Mallick <[hidden email]> wrote:
> >
> > Example:
> >
> >         local t = {}
> >         t.t = t
> >         assert((t == t.t) and (t.t == t.t.t) and (t.t.t == t.t.t.t))
> > -- and so on
> >
> > You remember _G, don't you?
> >
> >         assert(_G['_G'] == _G)
> >
> > --Sudipto Mallick
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

Scott Morgan
In reply to this post by 孙世龙 sunshilong
On 21/01/2021 11:23, 孙世龙 sunshilong wrote:

> Thank you for your detailed explanation.
>
> The assignment operator does almost the same thing both in Lua and
> Python whereas Python provides deepcopy() to do the aforementioned
> deep copy.
>
>> As you can see, there's a lot of possible ways to do this, as well as
>> potential issues, such as if there are recursive tables (tables that
>
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> link to themselves).
>   ^^^^^^^^^^^^^^^^^
> Could you give me a example(i.e recursive tables). I could not find much
> information about it on Google(keyword: Lua recursive tables).
>
> tab = {};
> tab ={tab};
> I don't think `tab` is a  recursive table indeed.

In that case, you've change the value of tab to a new table containing
the old value of tab.

tab = {}           -- tab points to a new table
tab.child = tab    -- tab.child points to the same table tab points to
tab = {tab}        -- tab now points to another table, which contains
                   -- the value tab used to point to

You might want to see the difference between 'values' and 'variables' here.

A variable points to a value, but is not the value itself.

Seems to be the same issue you had in your other thread[1]. Functions
are not passed variables, they're passed values.



[1] "How to acquire the name of the variables passes to the self-defined
C function which has been successfully set by lua_register()?"
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
Thank you for your clarification.

I think comparing the pointers of the outer table and inner table
could find out whether it's a recursive table or not.
Am I right? If I miss something,  please let me know.

On Thu, Jan 21, 2021 at 8:13 PM Scott Morgan <[hidden email]> wrote:

>
> On 21/01/2021 11:23, 孙世龙 sunshilong wrote:
> > Thank you for your detailed explanation.
> >
> > The assignment operator does almost the same thing both in Lua and
> > Python whereas Python provides deepcopy() to do the aforementioned
> > deep copy.
> >
> >> As you can see, there's a lot of possible ways to do this, as well as
> >> potential issues, such as if there are recursive tables (tables that
> >
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >> link to themselves).
> >   ^^^^^^^^^^^^^^^^^
> > Could you give me a example(i.e recursive tables). I could not find much
> > information about it on Google(keyword: Lua recursive tables).
> >
> > tab = {};
> > tab ={tab};
> > I don't think `tab` is a  recursive table indeed.
>
> In that case, you've change the value of tab to a new table containing
> the old value of tab.
>
> tab = {}           -- tab points to a new table
> tab.child = tab    -- tab.child points to the same table tab points to
> tab = {tab}        -- tab now points to another table, which contains
>                    -- the value tab used to point to
>
> You might want to see the difference between 'values' and 'variables' here.
>
> A variable points to a value, but is not the value itself.
>
> Seems to be the same issue you had in your other thread[1]. Functions
> are not passed variables, they're passed values.
>
>
>
> [1] "How to acquire the name of the variables passes to the self-defined
> C function which has been successfully set by lua_register()?"
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

Scott Morgan
On 21/01/2021 12:51, 孙世龙 sunshilong wrote:
> Thank you for your clarification.
>
> I think comparing the pointers of the outer table and inner table
> could find out whether it's a recursive table or not.
> Am I right? If I miss something,  please let me know.

It's complicated. You need to check each child table you copy against a
list of already seen tables that you need to maintain as you work
through everything.

Much easier to write this directly in Lua than in C (see the
lua-users.org link in an earlier post)
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
>It's complicated. You need to check each child table you copy against a
>list of already seen tables that you need to maintain as you work
>through everything.
I can't agree more.

>Much easier to write this directly in Lua than in C.
A self-defined function implemented by C makes easier for the users to
deep copy a table.

On Thu, Jan 21, 2021 at 9:17 PM Scott Morgan <[hidden email]> wrote:

>
> On 21/01/2021 12:51, 孙世龙 sunshilong wrote:
> > Thank you for your clarification.
> >
> > I think comparing the pointers of the outer table and inner table
> > could find out whether it's a recursive table or not.
> > Am I right? If I miss something,  please let me know.
>
> It's complicated. You need to check each child table you copy against a
> list of already seen tables that you need to maintain as you work
> through everything.
>
> Much easier to write this directly in Lua than in C (see the
> lua-users.org link in an earlier post)
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

Peter Loveday

> On 22 Jan 2021, at 11:31, 孙世龙 sunshilong <[hidden email]> wrote:
>
>> It's complicated. You need to check each child table you copy against a
>> list of already seen tables that you need to maintain as you work
>> through everything.
> I can't agree more.
>
>> Much easier to write this directly in Lua than in C.
> A self-defined function implemented by C makes easier for the users to
> deep copy a table.

It’s no easier or harder for a user to use a C function vs a Lua function.

It is, however, quite a bit easier to implement these things in Lua.  Doing it in C is messy.

- Peter
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
>>> Much easier to write this directly in Lua than in C.
>> A self-defined function implemented by C makes easier for the users to
>> deep copy a table.
>
>It’s no easier or harder for a user to use a C function vs a Lua function.
>It is, however, quite a bit easier to implement these things in Lua.  Doing it in C is messy.

If it's implemented in Lua, it requires the users to call `require`
function before invoking the deep copy function.
It seems an extra work for the users. Is there any method to avoid
this operation?

Best regards

On Fri, Jan 22, 2021 at 9:43 AM Peter Loveday <[hidden email]> wrote:

>
>
> > On 22 Jan 2021, at 11:31, 孙世龙 sunshilong <[hidden email]> wrote:
> >
> >> It's complicated. You need to check each child table you copy against a
> >> list of already seen tables that you need to maintain as you work
> >> through everything.
> > I can't agree more.
> >
> >> Much easier to write this directly in Lua than in C.
> > A self-defined function implemented by C makes easier for the users to
> > deep copy a table.
>
> It’s no easier or harder for a user to use a C function vs a Lua function.
>
> It is, however, quite a bit easier to implement these things in Lua.  Doing it in C is messy.
>
> - Peter
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

Peter Loveday


> On 22 Jan 2021, at 12:25, 孙世龙 sunshilong <[hidden email]> wrote:
>
>>>> Much easier to write this directly in Lua than in C.
>>> A self-defined function implemented by C makes easier for the users to
>>> deep copy a table.
>>
>> It’s no easier or harder for a user to use a C function vs a Lua function.
>> It is, however, quite a bit easier to implement these things in Lua.  Doing it in C is messy.
>
> If it's implemented in Lua, it requires the users to call `require`
> function before invoking the deep copy function.
> It seems an extra work for the users. Is there any method to avoid
> this operation?

Well that’s up to your application/environment choices.

I have no idea how you’re including your C functions, whether it’s a loadable module or you’re embedding the interpreter and manually registering them... but of course you can include Lua functions in similar ways, whether that be via executing a string, a file, a module, or whatever.  This may be dependent on how you intend to distribute it, whether you want to have source files visible or include them in a binary...

This is down to how you choose to structure your environment though.  Given an appropriate setup, there’s no difference as far as the user is concerned… they shouldn’t need to know if they’re calling C or Lua, ideally.

- Peter
Reply | Threaded
Open this post in threaded view
|

Re: Create a new table based on an already existed table (through Lua or C API)?

孙世龙 sunshilong
>I have no idea how you’re including your C functions, whether it’s a loadable module or you’re embedding the interpreter and manually registering them
Embedding the interpreter and manually registering them through
lua_register() function.

>whether you want to have source files visible or include them in a binary
It's better to have the source files invisible to avoid unintended
modification by the users.

-Sunshilong


On Fri, Jan 22, 2021 at 10:02 AM Peter Loveday <[hidden email]> wrote:

>
>
>
> > On 22 Jan 2021, at 12:25, 孙世龙 sunshilong <[hidden email]> wrote:
> >
> >>>> Much easier to write this directly in Lua than in C.
> >>> A self-defined function implemented by C makes easier for the users to
> >>> deep copy a table.
> >>
> >> It’s no easier or harder for a user to use a C function vs a Lua function.
> >> It is, however, quite a bit easier to implement these things in Lua.  Doing it in C is messy.
> >
> > If it's implemented in Lua, it requires the users to call `require`
> > function before invoking the deep copy function.
> > It seems an extra work for the users. Is there any method to avoid
> > this operation?
>
> Well that’s up to your application/environment choices.
>
> I have no idea how you’re including your C functions, whether it’s a loadable module or you’re embedding the interpreter and manually registering them... but of course you can include Lua functions in similar ways, whether that be via executing a string, a file, a module, or whatever.  This may be dependent on how you intend to distribute it, whether you want to have source files visible or include them in a binary...
>
> This is down to how you choose to structure your environment though.  Given an appropriate setup, there’s no difference as far as the user is concerned… they shouldn’t need to know if they’re calling C or Lua, ideally.
>
> - Peter