[Home] [Downloads] [Search] [Help/forum]

Gammon Forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Lua
. . -> [Subject]  Is it possible to iterate through a list of tables created in the script?
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

Is it possible to iterate through a list of tables created in the script?

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


Posted by Bobble   Canada  (76 posts)  [Biography] bio
Date Tue 30 Dec 2008 03:50 PM (UTC)

Amended on Tue 30 Dec 2008 03:57 PM (UTC) by Bobble

Message
Greets all,

In the script I'm working with, I've created several tables. I would like to associate several of them with a metatable I've created.

However, I would like to avoid having to manually associate each of these tables with the metatable as this is time consuming. Especially if I decide to add several more tables in the future.

I am curious if there is a way to iterate through all the tables that have been created in the script. I know that lua must store a list of its tables that have been created somewhere, is there a way to access that list?

All the tables I want to associate with my metatable end with _list. ie. name_list, class_list, cure_list. So I was thinking there must be a way to iterate through the list of tables that has been created and run an IF statement to associate them with the metatable, as so:

if string.sub(tablename, -4) == "list" then
     setmetatable(tablename, mt) -- mt is the name of the metatable I've created
end


Any thoughts on how this might be achieved?


Open the watch.
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #1 on Tue 30 Dec 2008 04:14 PM (UTC)
Message
Lua does not in fact store a list of created tables, although there is a list of global variables in the variable _G. In principle, you could search _G's keys to find names ending in "list", test _G[k] for type table, and then do your thing. But this is not good (see below).

Why is it so bad to associate the metatable as soon as the table is created?

my_nifty_list = {}
set_metatable(my_nifty_list, mt)


or:

function make_table()
  t = {}
  set_metatable(t, mt)
  return t
end


then when you want to create these tables:

my_nifty_list = make_table()

that's just one utility function, that you can stick somewhere; surely a function call is not time consuming or inconvenient?

Generally speaking, iterating over the list of global variables is rather flaky and dangerous, so you should avoid it as much as possible. You're introducing subtle behavior; maybe some day you'll create a new global ending in list, and that will get the metatable associated with it even though you might not have intended that.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Bobble   Canada  (76 posts)  [Biography] bio
Date Reply #2 on Tue 30 Dec 2008 04:22 PM (UTC)
Message
Hi David!

That function is perfect. Thanks a bunch for your help!

Open the watch.
[Go to top] top

Posted by WillFa   USA  (525 posts)  [Biography] bio
Date Reply #3 on Tue 30 Dec 2008 05:16 PM (UTC)
Message
Just to make it a little more robust...


function withmeta(...) 
  local t = {...} 
  local meta = {__index = function() return "hi" end }
  if #t == 1 and type(t[1])=="table" then 
    return setmetatable(t[1], meta) 
  else 
    return setmetatable(t, meta) 
  end
end


This lets you do things like:

foo = withmeta (4,5,6)  -- returns a new table with those values
foo = withmeta {first = 1, second = 2} --sets the metatable on that newly constructed table.
local bar = {5,6,7}
foo = withmeta(bar) -- returns the table with meta attached
foo = withmeta ()  -- new empty table with meta



[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #4 on Tue 30 Dec 2008 05:44 PM (UTC)
Message
I wouldn't make the metatable a local variable of the function. Not only is that wasteful (a copy of the same thing is created for every table), but also you can't test for metatable equality, which is something you occasionally need to do.

Also, you can't create a table that only contains a table using that method; it'll associate the metatable only with the contained table (and return that).

Otherwise, I like the idea of passing the ... argument to the table constructor.

Note that:
local bar = {5,6,7}
foo = withmeta(bar) -- returns the table with meta attached

Is setting the metatable on bar as well, because t = {bar}, and t[1]'s metatable is set. The above syntax makes it look like foo is a copy with the metatable attached, not touching the original.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] 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.


4,729 views.

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

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

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

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at FutureQuest]