Thread Tools Display Modes
03/24/15, 04:27 PM   #1
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
table.sort (parameter is nil)?

What could cause the parameter of a function, used in a table.sort(..., function), to have a nil parameter?

In one of my sorts in TextureIt I just encountered an error "Attempt to index a nil value" and I'm not sure how it is happening. It is random, it isn't tied to any specific search. For example I've just been searching "open" & "close" (without quotes). I just keep reloading the ui and doing the searches, sometimes both searches work, sometimes the second parameter passed to the sort function is nil.

I tried saving a reference to the table I'm sorting & examining it with /zgoo whenever the error occurs, but it looks ok to me?

Code that calls the sort & sort code:
Warning: Spoiler


I'm not sure if this part has anything to do with it, but I'll include it anyways. This is where the searchResults table gets populated. I pass in a destination table (searchResults) to save the matches into because of the recursion. So I don't have to copy the returned results each time the recursion happens.
Warning: Spoiler


Anyone have any ideas why table.sort would pass in a nil parameter to my sort function?
  Reply With Quote
03/24/15, 04:46 PM   #2
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 5,002
For me it looks that your function GetSearchResults() will build up a new table with the values of ALL your textues and paths that match to the searched string.
But you'll build a table "searchResults " with non-digit keys here!
Or does your table TEXTUREIT_TEXTURES store the key as digits? It looks like you are using text "name of texture" = texture "path to texture"?

The function table.sort will only sort, as far as I know, tables with non-alphanumeric key values. Only digits work properly.
I guess you'll have to transfer your searchResults table into another table with digits as key and then sort it by your sortfunction and afterwards transfer the results back to your wished output table.

Maybe this helps although I'm not sure if this explains the NIL stuff somehow ^^
  Reply With Quote
03/24/15, 04:56 PM   #3
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Baertram View Post
For me it looks that your function GetSearchResults() will build up a new table with the values of ALL your textues and paths that match to the searched string.
Yes that is what it does.

Originally Posted by Baertram View Post
But you'll build a table "searchResults " with non-digit keys here!
Or does your table TEXTUREIT_TEXTURES store the key as digits? It looks like you are using text "name of texture" = texture "path to texture"?
TEXTUREIT_TEXTURES -- does not store its elements with numeric keys. Yes (ignoring all of the tables inside it, it does eventually come down to) textureName = texturePath
But that doesn't matter because searchResults has numeric keys, everything that gets put into the searchResults table is inserted with:
Lua Code:
  1. -- destTable is the searchResults table
  2. table.insert(destTable, {["text"] = key, ["texturePath"] = value})
and the table.insert function automatically handles the positioning of entries into the table and it inserts them with numeric keys.
So for example:
Lua Code:
  1. local temp = {}
  2. table.insert(temp, {...somestuff...})
  3. table.insert(temp, {...someOtherStuff...})
  4.  
  5. -- would give us:
  6. temp = {
  7.   [1] = {...somestuff...}
  8.   [2] = {...someOtherStuff...},
  9. }

EDIT: By the way, just incase I had missed something & something was getting added to the table without a numeric key I did check it.
That is why I added the line:
Lua Code:
  1. someTempTable = searchResults
So that when the error occurred I could /zgoo someTempTable & make sure that all entries were stored with numeric keys & that no entries were missing. Everything looked ok.

Last edited by circonian : 03/24/15 at 05:04 PM.
  Reply With Quote
03/24/15, 05:29 PM   #4
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 5,002
Oh yes, I didn't think it to the end.... table.insert does use numeric index automatically, right.

The only explanation why searchResults[index].text would be nil then is: Because it was added to destTable[index] already with a nil value.
But I bet you already checked this
  Reply With Quote
03/24/15, 05:55 PM   #5
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Baertram View Post
The only explanation why searchResults[index].text would be nil then is: Because it was added to destTable[index] already with a nil value.
Thats not the error I'm getting (although i did check that anyway, none of them are nil).

The error is "Attempting to index a nil value" NOT "Operation < is not supported for string < nil"
"Attempting to index a nil value" -- Means that the entire table, tableB itself is nil (not just tableB.text)

Lua Code:
  1. local function tableSort(tableA, tableB)
  2.     -- tableA is always ok
  3.     if not tableA then d("Not tableA") end
  4.     -- tableB is nil "sometimes"
  5.     if not tableB then d("Not tableB") end
  6.    
  7.     -- error: "Attempt to index a nil value" (tableB is nil)
  8.     if tableA.text <= tableB.text then return true end
  9.     return false
  10. end
  Reply With Quote
03/24/15, 06:59 PM   #6
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Haven't tested anything, but I think table.sort might get confused by your comparing less-or-equal instead of less.
Sort functions commonly require strict total order, that is if cmp(a, b) then not cmp(b, a). Your comparator, when presented with a={text="foo"} and b={text="foo"}, returns true for both tableSort(a, b) and tableSort(b, a); but it should return false for equivalent items.
  Reply With Quote
03/24/15, 07:11 PM   #7
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by merlight View Post
Haven't tested anything, but I think table.sort might get confused by your comparing less-or-equal instead of less.
Sort functions commonly require strict total order, that is if cmp(a, b) then not cmp(b, a). Your comparator, when presented with a={text="foo"} and b={text="foo"}, returns true for both tableSort(a, b) and tableSort(b, a); but it should return false for equivalent items.
Ah I didn't know that. I tried printing out what items it was comparing and everytime it crashed it, it crashed after these two comparisons:
somestring <= somestring
somestring <= somestring
Where it compared some text value to itself twice. I guess that explains why! If it requires a strict comparison/order it couldn't determine which one came first because both evaluations would return true.

I never would have thought of that, thanks!
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » table.sort (parameter is nil)?


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