Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ Lua
➜ Metafunction __newindex calling itself
Metafunction __newindex calling itself
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Sat 11 Nov 2006 06:09 PM (UTC) |
Message
| I want to create a function to use to initialize variable tables that will serialize themselves whenever something is changes within them. The only way I could think of doing this is with the metafunction __newindex. But since it seems to call itself I am getting a stack overflow error and it halts. Anyone know how do go about doing this?
require "serialize"
function VarInit(name)
-- Declare and load the table
_G[name] = {}
if GetVariable(name) then loadstring(GetVariable(name))() end
-- Set the metatable to save itself
setmetatable(_G[name], {
__index = function(t, k)
return t['_' .. k]
end,
__newindex = function(t, k, v)
_G[name]['_' .. k] = v
SetVariable(name, serialize.save(name))
end
})
end
|
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #1 on Sat 11 Nov 2006 06:47 PM (UTC) |
Message
| The problem is that you create an infinite number of new variables. Let's say you add the variable "foobar". The way your newindex works, it'll create _foobar. But that's a new index, so it creates __foobar... and ___foobar... and so forth.
What you probably want to do is make sure that the first character isn't an underscore before renaming it as you set the value. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #2 on Sat 11 Nov 2006 07:09 PM (UTC) |
Message
| That's how I tried doing it before, but since I wouldn't work I tried this approach, renaming them. |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #3 on Sat 11 Nov 2006 08:25 PM (UTC) |
Message
| Would you mind pasting the code you had before? |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Nick Gammon
Australia (23,140 posts) Bio
Forum Administrator |
Date
| Reply #4 on Sun 12 Nov 2006 04:43 AM (UTC) |
Message
| A variation on the technique described in http://www.gammon.com.au/forum/?id=4904 might work for you, as it maintains an empty "proxy" table, and access to the real data are view __newindex. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #5 on Sun 12 Nov 2006 08:37 PM (UTC) |
Message
| Before I had something like ..
require "serialize"
function VarInit(name)
-- Declare and load the table
_G[name] = {}
if GetVariable(name) then loadstring(GetVariable(name))() end
-- Set the metatable to save itself
setmetatable(_G[name], {
__newindex = function(t, k, v)
SetVariable(name, serialize.save(name))
_G[name][k] = v
end
})
end
I've resorted to static names for my variables for now, but I'd still like a solution for this if anyone care to point me in a direction.
Using the proxy table to MUSHclient variables wouldn't work for me, since I'd need the variable to exist as a table (for iteration purposes). I could, ofcourse, track the initialized tables and serialize them when I finish my session. But I wanted to avoid doing that. Looks like a dead end to me. :/ |
Simplicity is Divine | http://nogfx.org/ | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #6 on Sun 12 Nov 2006 09:09 PM (UTC) |
Message
| After reading through the Lua documentation, it appears that you need to use rawset to directly set the table value, bypassing __newindex. If you don't, Lua has no way to realize that you set the field from inside __newindex and will simply call it again.
So you'd do something like this:
setmetatable(_G[name], {
__newindex = function(t, k, v)
SetVariable(name, serialize.save(name))
rawset(t,k,v)
end
})
(You might want to note that the 't' parameter is the current table. In your old code, even without the stack overflow, it was not a bug but a problem to explicitly refer to the table by name. With the new code, you can create the metatable only once and share it, thus saving some memory, instead of creating one copy per variable. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| tobiassjosten
Sweden (79 posts) Bio
|
Date
| Reply #7 on Mon 13 Nov 2006 10:43 PM (UTC) |
Message
| Never heard of the rawset function before. I'll try this out asap, thanks alot for the help! |
Simplicity is Divine | http://nogfx.org/ | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
22,487 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top