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.
Entire forum
➜ MUSHclient
➜ Lua
➜ Accessing MUSHclient variables via a table
Accessing MUSHclient variables via a table
|
Posting of new messages is disabled at present.
Refresh page
Posted by
| Nick Gammon
Australia (23,122 posts) Bio
Forum Administrator |
Date
| Wed 24 Nov 2004 03:15 AM (UTC) |
Message
| Lua starts to come into its own with its powerful support for what it calls "metatables".
By using these, we can greatly simplify the things you do a lot of in MUSHclient - accessing variables.
How many times have you written something like this in VBscript? ...
dim coins
coins = CInt (GetVariable ("coins"))
coins = coins + CInt (wildcards (2))
SetVariable "coins", coins
Here we have to muck around using GetVariable and SetVariable, as well as use CInt to convert strings into numbers.
Wouldn't it be nice to be able to write:
coins = coins + wildcards (2)
... and have that saved as a MUSHclient variable? Well, with Lua you can (almost).
To do this we need to create a dummy table, like this:
var = {} -- variables table
We will use that as our gateway to access MUSHclient variables. Now to make that work we need to make a "metatable" which implements two functions:
- __index - which is called when we attempt to get data from it
- __newindex - which is called when we attempt to add to it
These functions will call GetVariable and SetVariable to interface with MUSHclient variables.
Here is how it could look:
var = {} -- variables table
setmetatable (var,
{
-- called to access an entry
__index =
function (t, name)
return GetVariable (name)
end;
-- called to change or delete an entry
__newindex =
function (t, name, val)
local result
if val == nil then -- nil deletes it
result = DeleteVariable (name)
else
result = SetVariable (name, tostring (val))
end
-- warn if they are using bad variable names
if result == error_code.eInvalidObjectLabel then
error ("Bad variable name '" .. name .. "'")
end
end;
})
You could put that into your script file to be run when the world file opens. Now with that in place, we simply do this:
var.coins = var.coins + wildcards [2]
The "trick" here is the use of the "var" table - when we get data from that, or add to it, we go through the metamethod, which calls GetVariable and SetVariable, as shown above.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Larkin
(278 posts) Bio
|
Date
| Reply #1 on Fri 09 Mar 2007 03:22 PM (UTC) |
Message
| I use a lot of numbers in my Lua coding, and I didn't want to always have to convert the MUSHclient string variables to numbers for comparison. I modified this module a tiny bit to do the conversion for me after a simple check for a "numbers only" string. You could easily do the same for true/false, if you wanted. My var index function now looks like this:
function (t, name)
local v = GetVariable(name)
if (v == tostring(tonumber(v))) then
return tonumber(v)
end
return v
end
| Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #2 on Fri 09 Mar 2007 04:14 PM (UTC) |
Message
| Alternatively, you could check the return value of tonumber against nil:
function (t, name)
local v = GetVariable(name)
local n = tonumber(v)
if n ~= nil then
return n
end
return v
end
The ~= nil part is optional, since any number (including 0) is considered to be true. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Ked
Russia (524 posts) Bio
|
Date
| Reply #3 on Fri 09 Mar 2007 04:37 PM (UTC) |
Message
| You could actually make it even simpler:
function (t, name)
local v = GetVariable(name)
return tonumber(v) or v
end
| Top |
|
Posted by
| Larkin
(278 posts) Bio
|
Date
| Reply #4 on Fri 09 Mar 2007 06:01 PM (UTC) |
Message
| Good points, guys. Thanks for the tips. Sometimes I just don't think of the shortest, or even the easiest, way to code something. My purpose was more to suggest that Nick add something like this to his version of var.lua for future MUSHclient distributions. :) | Top |
|
Posted by
| Nick Gammon
Australia (23,122 posts) Bio
Forum Administrator |
Date
| Reply #5 on Sat 10 Mar 2007 12:48 AM (UTC) Amended on Sat 10 Mar 2007 12:51 AM (UTC) by Nick Gammon
|
Message
| I think it would be better for individual coders to make the suggested change, if they want to. Changing from a string to a number can't necessarily be reversed. For example:
a = tonumber ("1234e343")
print (a) --> 1.#INF
a = tonumber ("143123412431243124124312431234132")
print (a) --> 1.4312341243124e+032
It might happen that someone is using variables to store things like that and simply accessing the variable, and re-storing it, should not change it.
You could conceivably make the function do this:
function (t, name)
local v = GetVariable(name) -- fetch variable
local n = tonumber (v) -- try to make number
if n and tostring (n) == v then -- reversible?
return n -- ok, return number
else
return v -- better return string
end -- if
end -- function
This is now doing a tonumber and maybe a tostring on every access - perhaps you don't want the speed decrease.
Even that suggestion would not be foolproof, for example a string containing "-01" once converted to a number and back again is "-1". I suppose it depends on whether you are certain you are dealing with numbers or not. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,122 posts) Bio
Forum Administrator |
Date
| Reply #6 on Sat 29 Mar 2008 08:29 PM (UTC) Amended on Sat 29 Mar 2008 08:34 PM (UTC) by Nick Gammon
|
Message
| This "var" code now ships as part of MUSHclient (from version 3.80 onwards), in a separate module file called var.lua.
If you have things installed in their default locations, all you have to do is "require" it like this:
require "var"
var.coins = var.coins + wildcards [2]
The "require" line pulls in all of the code described above, all you have to do is go ahead and use it.
In an example like the above one, you need to be cautious that the variable exists (as a MUSHclient variable). Otherwise you are doing arithmetic on a nil value, which will fail. This approach can solve that:
require "var"
var.coins = (var.coins or 0) + wildcards [2]
The "or 0" part says, in effect: if var.coins is nil, use 0 instead (as a default)
A more long winded way of achieving the same thing is:
require "var"
if var.coins == nil then
var.coins = 0
end -- if variable does not exist
var.coins = var.coins + wildcards [2]
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | 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.
33,385 views.
Posting of new messages is disabled at present.
Refresh page
top