This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Pharap's profile picture

C pointers in Lua?

Started by Pharap, 30 October 2012 - 06:20 AM
Pharap #1
Posted 30 October 2012 - 07:20 AM
I was doing some OO in lua when I hit a bit of a snag that made me beg the question:
are there ways of doing pointers in lua?

I was trying to make an object that stored certain things in an internal table, but allowed some of it to be referenced outside of the table
eg:


User = {}
User.data = {}
User.Username = (point to User.data.username)
User.Password = (point to User.data.ScramblePassword())

I tried making the data table have functions that returned the data and setting the values I wanted to refer to that data to the results of those functions like so:


Triangle = {}
Triangle.vector1 = {}
Triangle.vector1.x = 0
Triangle.vector1.refx = function() return Triangle.vector1.x = 0 end
Triangle.X = Triangle.vector1.ref()

But this didn't work because Triangle.X is then technically a value type, not a reference type.
I don't want to use functions as a reference type like so:



Triangle = {}
Triangle.vector1 = {}
Triangle.vector1.x = 0
Triangle.X = function() return Triangle.vector1.x = 0 end

Because that would mean having to call Triangle.X() and the brackets are unnatural and not very user friendly.
Ultimately I want to achieve this:

Triangle.X = (points to)Triangle.vector1.x
--so that--
Triangle.X = 5
print(Triangle.X) --prints 5
print(Triangle.vector1.x) --prints 5

Triangle.vector.x = 10
print(Triangle.X) --prints 10
print(Triangle.vector1.x) --prints 10

so really what I want to know is:

A) Does lua have pointers in a way that I can make an object member point to a place storing a value type without having to call that member as a function (ie with brackets)?

B)If not, is there a way this can be replicated with metatables, for example storing the value as a table and have it's reference refer to an internal value as opposed to that table's place in memory?
KaoS #2
Posted 30 October 2012 - 07:34 AM
you can do both with metatables.


User = {}
User.data = {}
User.Username = setmetatable({},{__tostring=function(tMe) return User.data.username end})
User.Password = setmetatable({},{__tostring=function(tMe) return User.data.ScramblePassword end})

but that only works if you try to get User.username as a string so I prefer the second method


User = {}
User.data = {}
setmetatable(User,{__index=User.data})

basically if you try User.randomvalue it will look in Users for randomvalue but if it does not find it then it will look in Users.data
Pharap #3
Posted 30 October 2012 - 10:38 AM
Thanks for the help, I looked it up beforehand anyway and manage to decipher that __index and __newindex can essentially be used as get and set accessors.
I find a lot of lua tutorials tend to be garbled or not discuss things in standard programming terms, hence I understood the example code given more than the actual explanation they gave.
KaoS #4
Posted 30 October 2012 - 10:46 AM
hahaha. take a look here for a great tutorial. the adding and other math metatables are great for co-ordinate based programs and rendering etc
Pharap #5
Posted 30 October 2012 - 10:54 AM
For once, a lua tutorial that's actually decent, and that's saying something.
KaoS #6
Posted 30 October 2012 - 11:09 AM
lmao. so true :P/>/> I wonder if there are any other metatable tags that I don't know about though :P/>/> they are incredibly useful and I would love to know them all. if you hear of any other ones let me know please
Pharap #7
Posted 30 October 2012 - 11:56 AM
There's also __len according to http://pgl.yoyo.org/luai/i/2.8+Metatables
len is the # operator that gets the length of tables and strings (very handy, much quicker than calling table.maxn and string.len).

As well as __metatable according to http://lua-users.org/wiki/MetatableEvents
__metatable stops the metatable being altered, so it's good to add for preventing people changing the metatable of an object you've made.

__tostring is obvious and most people probably wouldn't use it,
however if you're doing OO like me, you may want to make it return the name of the class since lua treats all objects as tables, and thus doesn't respect the concept of classes, making it hard to check that the table you are using is of the right object-type, and thus make it hard to determine if the object/table will have the desired properties and functions that you want. By making tostring default to the class type, you can just check the tostring function to see if someone is trying to throw you a table that isn't of that object type.

there's also __mode, but since I can't force garbage collect, I was unable to test it.
KaoS #8
Posted 30 October 2012 - 11:59 AM
__metatable is for when they try to get your metatable. if they already have that then they can go ahead and change it.
unless you set it to be 'protected' in which case Lua is coded not to change it I think

I also find that the __call metatable is great. you can make a function that stores its components in its own table in case you need them (I used that for a great counter function)
Pharap #9
Posted 30 October 2012 - 02:01 PM
If you're setting the metatable for an object used in an API then after using __metatable nobody can use that table unless they have access to the API and change things. Programatically, if you only ever set the table once, you should be able to make it stay that object's readonly metatable.

I would be tempted to try and use the __call as the table's "constructor", which may end horribly. I'd also consider using it as an alternative to that 'tostring' returning the class idea I had before, by making the table call return the class string. Either that or switch the two so calling the table returns its tableref and calling tostring returns the class string.

Metatables really are an entire other level of OO altogether.
KaoS #10
Posted 30 October 2012 - 02:05 PM
what I did is a function that generates a new table when it is called so you say

a=counter()

and from then on 'a' is a table with the count in it and all the counting functions - similar to the way vector works


I would be tempted to try and use the __call as the table's "constructor", which may end horribly. I'd also consider using it as an alternative to that 'tostring' returning the class idea I had before, by making the table call return the class string. Either that or switch the two so calling the table returns its tableref and calling tostring returns the class string.

Metatables really are an entire other level of OO altogether.

metatables are my Favorite part of Lua. they add an entirely new dimension to it