Register forum user name Search FAQ

Gammon Forum

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 ➜ How do I access tables created in one function from another?

How do I access tables created in one function from another?

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Bevern   (9 posts)  Bio
Date Sat 02 Aug 2008 09:43 PM (UTC)
Message
I'm trying to make an xp tracker that tracks the last hour's experience gained and this is what I have thus far:


function newrecord (name, line, wildcards)

	if tracking == nil then
		tracking = {}
	end -- if
	record = {}
	record.xp = wildcards [1]
	record.time = os.time()
	table.insert(tracking, record)

end -- function

function showxp (name, line, wildcards)
	xphour = 0
	while next(tracking) ~= nil do
		record = tracking[1]
		print (record.time)
		if record.time < os.time() - 3600 then
			table.remove(tracking, 1)
		else -- Everything after is newer
			xphour = xphour + record.xp
		end -- if
	end -- while
	print ("Experience gained this hour: " .. xphour)
end --function


But when running showxp it gives me the error message

Run-time error
World: Aardwolf
Function/Sub: showxp called by alias
Reason: processing alias ""
[string "Script file"]:15: bad argument #1 to 'next' (table expected, got nil)
stack traceback:
        [C]: in function 'next'
        [string "Script file"]:15: in function <[string "Script file"]:13>
Error context in script:
  11 : end -- function
  12 : 
  13 : function showxp (name, line, wildcards)
  14 :  xphour = 0
  15*:  while next(tracking) ~= nil do
  16 :          record = tracking[1]
  17 :          print (record.time)
  18 :          if record.time < os.time() - 3600 then
  19 :                  table.remove(tracking, 1)


Which seems to me that it's saying either the table isn't saving after the newrecord function runs or there's some other way to access tables that aren't created by the executing function. What am I doing wrong here? Thanks
Top

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #1 on Sat 02 Aug 2008 10:47 PM (UTC)
Message
You have the right general idea, but are you sure that newrecord was called before showxp? Perhaps some print statements to make sure.

If the first thing you do, after reloading the script file, is to do showxp, then the tracking table won't exist. Maybe do this:


function showxp (name, line, wildcards)
	xphour = 0
        tracking = tracking or {}  --> make sure table exists


Meanwhile, won't this go into an infinite loop?


while next(tracking) ~= nil do
		record = tracking[1]
		print (record.time)
		if record.time < os.time() - 3600 then
			table.remove(tracking, 1)
		else -- Everything after is newer
			xphour = xphour + record.xp
		end -- if
	end -- while


Once you stop removing records that are over an hour old, it will loop forever.

Perhaps:


for k, record in pairs (tracking) do
  print (record.time)
  if record.time < os.time() - 3600 then
    tracking [k] = nil  -- delete old records
  else -- Everything after is newer
    xphour = xphour + record.xp
  end -- if
end -- for


This will step through the table once, deleting old records, and add up xp.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Bevern   (9 posts)  Bio
Date Reply #2 on Tue 05 Aug 2008 06:21 AM (UTC)
Message
Thanks, that worked great. Another question: I'm trying to serialize the table into a string so I can save it as a variable and then reload it. I used the serialize.lua script and amended "require "serialize"" to the top of the script but I get this when I try to run it:

Run-time error
Plugin: Aardwolf_Level_Tracker (called from world: Aardwolf)
Function/Sub: showexpt called by alias
Reason: processing alias ""
[string "Plugin"]:270: attempt to index global 'serialize' (a nil value)
stack traceback:
        [string "Plugin"]:270: in function <[string "Plugin"]:252>
Error context in script:
270*:  print ("stats = " .. serialize.save (statstable))

Top

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #3 on Tue 05 Aug 2008 10:07 AM (UTC)
Message
Can you show the exact code? If I saw this:


require "serialize"  

print ("stats = " .. serialize.save (statstable))

...

[string "Plugin"]:270: attempt to index global 'serialize' (a nil value)


... I would be surprised.

However maybe the "require" line was not executed.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Bevern   (9 posts)  Bio
Date Reply #4 on Wed 06 Aug 2008 02:24 AM (UTC)
Message
It seems the problem I was having is that the "require" must be inside the function calling it rather than something global(unless I'm mistaken). I've come across another problem with serializing however. Just for testing purposes I created the following two functions:



function test1 ()
	require "serialize"
	if GetVariable ("statstable") then
		loadstring (GetVariable ("statstable"))
	else
		statstable = statstable or {}
		statstable.currentlevel = 0
		statstable.resettime = os.time()
		statstable.totalbonuss = 0
		statstable.totalbonusi = 0
		statstable.totalbonusw = 0
		statstable.totalbonusd = 0
		statstable.totalbonusc = 0
		statstable.totalbonusl = 0
		statstable.totalbonustrains = 0
		statstable.totalgold = 0
		statstable.totalkills = 0
		statstable.totallevels = 0
		statstable.totalpups = 0
		statstable.totalremorts = 0
		statstable.totalxp = 0
		statstable.installtime = os.time()
	end -- if
	SetVariable ("statstable", serialize.save ("statstable"))
end

function test2 ()
	loadstring (GetVariable ("statstable")) 
	print (statstable.totalxp)
end

First I create the table and then serialize it with test1 which results in the "statstable" variable becoming:


statstable = {}
  statstable.totalbonusw = 0
  statstable.installtime = 1217988982
  statstable.totalbonusi = 0
  statstable.totalbonusl = 0
  statstable.totalxp = 12341
  statstable.totalpups = 0
  statstable.resettime = 1217988982
  statstable.currentlevel = 0
  statstable.totalremorts = 0
  statstable.totallevels = 0
  statstable.totalkills = 0
  statstable.totalbonusc = 0
  statstable.totalbonusd = 0
  statstable.totalbonuss = 0
  statstable.totalgold = 0
  statstable.totalbonustrains = 0


This seems strange since I'd think the brackets should end after the last line, not just be {}

Test2 is supposed to load it and then print it's value. It seems that it's not loading correctly however because it still prints out the value of the table's totalxp value rather than loading it from the variable.
Top

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #5 on Wed 06 Aug 2008 02:44 AM (UTC)
Message
Quote:

This seems strange since I'd think the brackets should end after the last line, not just be {}


Why? You did it exactly the same way. You created the table in one line, and then changed all its contents.


statstable = statstable or {}
statstable.currentlevel = 0
statstable.resettime = os.time()
... etc.


Quote:

It seems the problem I was having is that the "require" must be inside the function calling it rather than something global(unless I'm mistaken).


It can be global, however I am doubting it was executed if it was nil.


Quote:

function test2 ()
loadstring (GetVariable ("statstable"))
print (statstable.totalxp)
end

It seems that it's not loading correctly however ...


Compare to my example at the bottom of this page:

http://www.gammon.com.au/forum/?id=4960

I had this:


function OnPluginInstall ()
  assert (loadstring (GetVariable ("my_variables") or "")) ()
end -- function OnPluginInstall


Note the extra brackets at the end of the line? Your "loadstring" created a function but didn't execute it, thus statstable was not changed. At least change it to:


function test2 ()
	loadstring (GetVariable ("statstable"))  ()
	print (statstable.totalxp)
end



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Bevern   (9 posts)  Bio
Date Reply #6 on Fri 08 Aug 2008 11:49 PM (UTC)
Message
Excellent, thank you very much.
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.


21,272 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.