Thread Tools Display Modes
02-24-09, 06:19 PM   #1
Hati-EK
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 20
Expanding tables with loops

I have a simple question ... my current test code (tested in Wowlua and Omnibus, both times the same error) seems to have a bug - but i am unable to get it ...


Error Message: attempt to index field '?' ( a nil value )

Testcode:
Code:
local x = {}
local k = 1

while name~=nil do
   local name,rank,rankIndex,level,LOclass,zone,_,_,online,status,englishClass =GetGuildRosterInfo(k)
   x[k].n="Test"
   x[k].r=rank
   x[k].l=level
   x[k].c=LOclass
   x[k].z=zone
   x[k].on=online
   x[k].realClass=englishClass
   k=k+1
end

DEFAULT_CHAT_FRAME:AddMessage(x[1].n)
hope someone can enlight me
  Reply With Quote
02-24-09, 06:51 PM   #2
DreamStorm
A Deviate Faerie Dragon
 
DreamStorm's Avatar
Join Date: Feb 2009
Posts: 15
I am kind of new to this lua game myself, so apologies if I am a little off the mark ....

I am assuming that you wish to create the data in the table from the returns from the GetGuildRosterInfo() method. Your while loop is set to test the name part of the return but you haven't got a value for that before you enter the loop; at least not the value you wish. As it is the while loop is essentially evaluating a global variable for nil value. I don't know if there is a global variable called name but if there isn't you're loop will never start as if will only do so if the value is not (~=) nil.

I think you would need to run that method outside the loop, then enter it, set the values and within the loop (at the end) rerun the method. I am not sure how lua handles reusing the varables in this way though. Something like ...

Code:
local x = {}
local k = 1

local name,rank,rankIndex,level,LOclass,zone,_,_,online,status,englishClass =GetGuildRosterInfo(k)
while name~=nil do
   x[k].n="Test"
   x[k].r=rank
   x[k].l=level
   x[k].c=LOclass
   x[k].z=zone
   x[k].on=online
   x[k].realClass=englishClass
   k=k+1   
   name,rank,rankIndex,level,LOclass,zone,_,_,online,status,englishClass =GetGuildRosterInfo(k)
end

DEFAULT_CHAT_FRAME:AddMessage(x[1].n)
You may have to give the returns from the method more specific global names rather than declare them local. Please someone correct me if I am wrong.
__________________


ultima ratio regum
  Reply With Quote
02-24-09, 07:21 PM   #3
Tuhljin
A Flamescale Wyrmkin
 
Tuhljin's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2008
Posts: 106
DreamStorm is right about name using the global variable name instead of the local one you want, but the actual error message is due to your trying to index a non-existent table. Try something like this:

Code:
local x = {}
local k = 1

-- Get name before the while loop:
local name,rank,rankIndex,level,LOclass,zone,_,_,online,status,englishClass =GetGuildRosterInfo(k)

while name~=nil do
   x[k] = {}
   x[k].n="Test"
   x[k].r=rank
   x[k].l=level
   x[k].c=LOclass
   x[k].z=zone
   x[k].on=online
   x[k].realClass=englishClass
   k=k+1
   name,rank,rankIndex,level,LOclass,zone,_,_,online,status,englishClass =GetGuildRosterInfo(k)
end

DEFAULT_CHAT_FRAME:AddMessage(x[1].n)
  Reply With Quote
02-25-09, 03:55 AM   #4
Hati-EK
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 20
yea thanks :P - after i went to bed yesterday ... it was quite clear to me ... maybe it was just to late ...

x[k] = {}
-> creates the indicies ?

like
x = {
[1] = { }
}

?

Last edited by Hati-EK : 02-25-09 at 03:58 AM.
  Reply With Quote
02-25-09, 04:44 AM   #5
Mera
Retired of WoW, In ESO :)
 
Mera's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Apr 2008
Posts: 331
yup in short you are using 2 tables without saying the second time the second is a table
__________________
If you need to reach me I'm in ESO, @class101 or "Fathis Ules i"
addons: SpamBayes, BrokerCPU
projects: ThunderBayes
Mera[xeh]? - La CroisadeEcarlate (wow)
  Reply With Quote
02-26-09, 10:11 AM   #6
Hati-EK
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 20
Question:
if i use 'break' like
Code:
for i=1,10 do
 while j<=x do
  if bla==1 then
   value1 = i
   value2 = j
   break
  end
 end
end
will the 'break'-command escape the for-loop too?
  Reply With Quote
02-26-09, 11:29 AM   #7
Slakah
A Molten Giant
 
Slakah's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2007
Posts: 863
Work it out for yourself.

Put this code
lua Code:
  1. local t, i = {cat = 1, dog = 2}, 0
  2. print("going")
  3. for _, _ in pairs(t) do
  4.    print("in for loop")
  5.    while true do
  6.       break
  7.    end
  8.    i = i + 1
  9.    if i == 2 then
  10.       print("Break does not break for loop")
  11.    end
  12. end

here http://www.lua.org/cgi-bin/demo
  Reply With Quote
03-01-09, 08:57 PM   #8
tsadok
An Aku'mai Servant
 
tsadok's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 32
Originally Posted by Hati-EK View Post
yea thanks :P - after i went to bed yesterday ... it was quite clear to me ... maybe it was just to late ...

x[k] = {}
-> creates the indicies ?

like
x = {
[1] = { }
}

?
Nearly... x[k] = {} requires x to be declared as a table, and x = { [1] = { } } declares both x and x[1] (using two sets of {} )
  Reply With Quote
03-02-09, 05:50 AM   #9
Mera
Retired of WoW, In ESO :)
 
Mera's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Apr 2008
Posts: 331
note that I did further test and creating multiple tables with loops in one table takes way much memory than creating multiple stable tables and just changing key and values without calling at other tables inside, I think it allocates way much memory and create a quite big garbarge for nothing helpful
  Reply With Quote
03-02-09, 07:39 AM   #10
ZikO
An Aku'mai Servant
Join Date: Jun 2008
Posts: 36
Originally Posted by Mera View Post
note that I did further test and creating multiple tables with loops in one table takes way much memory than creating multiple stable tables and just changing key and values without calling at other tables inside, I think it allocates way much memory and create a quite big garbarge for nothing helpful
That's too bad IMO. Tables in tables etc are great structures which help keeping the code tidy. I would like it but unfortunately it takes too much memory, sadly.
  Reply With Quote
03-03-09, 07:26 PM   #11
Hati-EK
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 20
Originally Posted by Mera View Post
note that I did further test and creating multiple tables with loops in one table takes way much memory than creating multiple stable tables and just changing key and values without calling at other tables inside, I think it allocates way much memory and create a quite big garbarge for nothing helpful
to say it simple:

Using 1dim tables is more efficient in speaking of memory usage than 2dim tables? dim = dimension
^ Ydim
|
|
-------> Xdim

?

and what about 1 stable 2dim-table - which is created once - required the whole time ... and just values are changed in?

Last edited by Hati-EK : 03-03-09 at 07:29 PM. Reason: question
  Reply With Quote
03-04-09, 09:43 AM   #12
ZikO
An Aku'mai Servant
Join Date: Jun 2008
Posts: 36
Thumbs down

Originally Posted by Hati-EK View Post
to say it simple:

Using 1dim tables is more efficient in speaking of memory usage than 2dim tables? dim = dimension
^ Ydim
|
|
-------> Xdim

?

and what about 1 stable 2dim-table - which is created once - required the whole time ... and just values are changed in?
Honestly I thought LUA could use some kind of efficient implementation like this:
Code:
table:                               <container>
    table1: **********               10 elements
    table2: *****                    5 elements
    table3:                          <sub-container>
        table31: ********            8 elements
        table32:                     <sub-sub-container>
            table321: *******        7 elements

    table4: ***
    table5:                          <sub-container>
        table51: ****                5 elements
        table52: **                  2 elements
where number of particular elements are simply added + little memory for storing tables in tables. If it looks like as you said, it means any kind of table more than 1 dimension is populating empty cells like this:
Code:
table:
    table1: ****--------
    table2: **----------
    table3: ************
18 elements waisted. etc. Cannot believe it :P
  Reply With Quote
03-05-09, 09:34 PM   #13
Tuhljin
A Flamescale Wyrmkin
 
Tuhljin's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2008
Posts: 106
I'm not an expert on this, but I don't think that's how it works. Tables can point to other tables, which can in turn point back to the a previous table (creating a "loop")... and then we've got the global table (_G).... I just don't see it working how you've described it. I saw an article about memory footprints in Lua that I wanted to link here, but of course now that I want it, I don't see it any more.
  Reply With Quote
03-06-09, 04:30 PM   #14
ZikO
An Aku'mai Servant
Join Date: Jun 2008
Posts: 36
I am just guessing that's all.

Anyway, I do not believe three single tables would take much more memory than one table containing all of them. Of course it would be a little more memory taken as there would be 4 tables not 3 as fourth would have to store 3 other tables

I would like someone to explain me that tables in tables is not a good idea.

Regards.
  Reply With Quote
03-15-09, 05:30 PM   #15
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Just force garbage collection at the end of your function. Problem solved.
  Reply With Quote
03-15-09, 05:52 PM   #16
spiel2001
nUI's Author
 
spiel2001's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2008
Posts: 7,724
Originally Posted by ZikO View Post
18 elements waisted. etc. Cannot believe it :P
The key to understanding Lua is that it is designed and built for runtime efficiency, not for memory conservation. Compacting tables is computationally expensive. It's easier and faster to use memory blocks and that's what Lua is all about is speed.

PS: Running the garbage collector at the end of a function call is a bad idea. It will cause the user display to hiccup (tear) every time the garbage collector fires. Better to let the background garbage collection deal with it when it's most efficient to do so.
__________________

What people don't get is that I am, ultimately, an artist at heart.
My brush has two colors, 1 and 0, and my canvas is made of silicon.



Official nUI Web Site: http://www.nUIaddon.com
Official nUI Support Forum: http://forums.nUIaddon.com
My day job: http://www.presidio.com/
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Expanding tables with loops


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off