Is there anything like pointers in Lua?

Tags: pointers lua
Question!

I'm new to Lua and I want to create a table [doh] which would store values like:

parent.child[1].value = "whaterver"
parent.child[2].value = "blah"

however, most often there's only one child, so it would be easier to access the value like this:

parent.child.value

To make things simpler, I would like to store my values, in a way, that

parent.child[1].value == parent.child.value

But to do this I would have to store this value twice in the memory. Is there any way I could do it, so that:

parent.child.value points to parent.child[1].value

without storing the value twice in the memory?

Additional question is, how to check how much memory does a table take?

By : Krystian


Answers

With C arrays, parent.child and parent.child[0] are equivalent because of pointer arithmetic. You really shouldn't try to emulate one of the most error-prone, confusing and redundant features of C just because you like the style.

By : Trevor C.


This is a nice application for using metatables:

parent={
    child={
        {value="whatever"},
        {value="blah"}
    }
}
setmetatable(parent.child,{__index=parent.child[1]})

If an index is not found in the child table (like 'value'), it gets looked up in the table that's the value of __index of the metatable (the first element of child in this case).

Now there is a problem with the above code which we can see as folows:

print(parent.child.value) -- prints whatever
parent.child[1]=nil --remove first child
print(parent.child.value) -- still prints whatever!

This is because the metatable keeps a reference to the first child table, preventing it from being reaped. The workaround for this kind of stuff is A) making the metatable a weak table, or B) make the __index field a function, instead of referencing it to a table.

-- A)
setmetatable(parent.child, setmetatable(
    {__index=parent.child[1]} -- metatable for the child table
    {__mode='v'}-- metatable for the metatable, making it have weak keys
    )
)
parent.child[1]=nil
print(parent.child.value) --returns nil
parent.child[1]={value='foo'} 
print(parent.child.value) -- prints nil, the metatable references to a non-existant table.
-- hence solution B)

setmetatable(parent.child, {__index=function(t,k) return parent.child[1][k]})
print(parent.child.value) -- 'whatever'
parent.child[1]=nil
print(parent.child.value) -- nil
parent.child[1]={value='foobar'
print(parent.child.value) -- foobar, now it will always refer to the table at child[1], even when it changes.

If you're really interested to read up on metatables, try reading Programming in Lua, chapter 13 and chapter 17 (weak tables). Lua-Users wiki on MetaMethods might also be interesting.

By : jpjacobs


Lua tables (often used as objects) are not copied, but referenced. (internally, a pointer is used to them)



This video can help you solving your question :)
By: admin