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
➜ SMAUG
➜ Lua
➜ Keeping a list of known fields
Keeping a list of known fields
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Sat 06 Sep 2008 03:52 AM (UTC) |
Message
| I have an object, the details of which aren't really important (it's a binding for characters), represented by a table in Lua-space. This object has many fields. Lua has no compile-time checking for whether or not a field exists, so there is no way for me to know if I made a typo when I access a field in the code. The best I can do, if I want to be sure that I'm accessing a field that's actually valid, is to have runtime checks against a list of known fields. Currently I'm doing this:
local priv_fields =
set.new({
"inputStatus", "inputCoroutine", "inputCommand",
"sendPrompt",
})
function __index(actor, key)
-- is this a known field?
if priv_fields:contains(key) then
return actor.__private[key]
end
-- is it a module field?
if _M[key] then
return _M[key]
end
-- we don't know what it is... ack
error("unknown actor field/method: " .. key)
end
function __newindex(actor, key, val)
-- if it's a known field, we can set it
if priv_fields:member(key) then
actor.__private[key] = val
return
end
-- can't assign to anything else...
error("can't assign to actor field: " .. key)
end
Every access to a field entails the indirection of the metatable. Admittedly, this is not very expensive: at worse it is just two table lookups. (Well, set:contains entails a function call that then does a table lookup. So that's two table lookups and a function call.)
Is this a reasonable solution? What are other people doing? Not having any kind of compile-time verification kind of bothers me, and implementing (or finding/figuring out somebody else's) static analysis is not something I really have time to do. I'm not happy with the runtime checks (their usefulness is directly proportional to the code's frequency of execution) but it's the best I'm seeing at the moment. |
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 #1 on Sat 06 Sep 2008 04:08 AM (UTC) |
Message
| Can't you just use __index without the hidden table? That way, an attempt to get a non-existent field will involve the check, but if the field has data in it, you assume it is good. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #2 on Sat 06 Sep 2008 04:15 AM (UTC) |
Message
| Do you mean only use __newindex? I want an error to be triggered when an unknown is either accessed or created. Doesn't that mean I need to use both?
Or did you mean that __index can see directly if the field exists in the actor? Something like this:
function __index(actor, key)
-- is this a known field?
if actor[key] then
return actor.__private[key]
end
-- is it a module field?
if _M[key] then
return _M[key]
end
-- we don't know what it is... ack
error("unknown actor field/method: " .. key)
end
The problem here is that some fields might legitimately be nil-valued, but still be known fields. How would you get around that? |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.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.
9,863 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top