pairs() vs next() with userdata objects?

Place to get help with not working mods / modding interface.
Post Reply
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

pairs() vs next() with userdata objects?

Post by eradicator »

So, for some time now i've been testing if i can use next instead of pairs, because i find it looks syntactically more pleasing (yes, i know there is no performance benefit). But yesterday i noticed something strange.

Take these two examples:

Code: Select all

/c for k,v in pairs(game.players) do print(v.name) end
This works fine.

Code: Select all

/c for k,v in next, game.players do game.print(v.name) end
This throws an "attempted to index userdata" error.

Upon further investigation i noticed that while pairs returns the expected table wrapper {__self=<userdata>}, next returns the <userdata> object without the table around it.

So my question is: Is this a bug? Am i just doing something stupid? Why does next work for normal tables but not for factorio rich objects?

Any help is appreciated.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

eduran
Filter Inserter
Filter Inserter
Posts: 344
Joined: Fri May 09, 2014 2:52 pm
Contact:

Re: pairs() vs next() with userdata objects?

Post by eduran »

Your issue is not about <userdata> objects, but about custom tables. Those can only be iterated over with the modified pairs() function Factorio provides. Retry your second example with something that returns a normal lua table of objects (e.g. game.get_train_stops()) and it will work.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: pairs() vs next() with userdata objects?

Post by eradicator »

The API doc calls both game.players and game.get_train_stops's return value an "array of X" though, so i wouldn't know what kind of table to expect even if i did know where it came from, which i don't. Hrmpf. Guess i'll be converting all the next's back to pairs, what a pity.

Thanks alot for the hint though, totally forgot about custom tables special behavior.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Bilka
Factorio Staff
Factorio Staff
Posts: 3159
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: pairs() vs next() with userdata objects?

Post by Bilka »

game.players says "custom dictionary uint or string", the "custom dictionary" part means that it is a LuaCustomTable.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: pairs() vs next() with userdata objects?

Post by eradicator »

I used ctrl+f "players"...and found "players :: array of LuaPlayer [Read-only]". That was players.force though, duh. Which suprisingly seems to be accurate. (Suprising in that force.players is *not* a custom table). All the more reason to go back to pairs everywhere :/.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

quyxkh
Smart Inserter
Smart Inserter
Posts: 1029
Joined: Sun May 08, 2016 9:01 am
Contact:

Re: pairs() vs next() with userdata objects?

Post by quyxkh »

Using `next` is a declaration that the table's a plain lua table. `pairs` looks up iterator arguments for what you pass it, if it's a plain lua table it returns `next` and the table, otherwise it uses whatever the metatable says. For lua tables that have a metatable with an overriding `__pairs`, using `next` will bypass that, which might or might not be what you want; for custom tables (i.e. userdata tables), where pretty much the entire point is not to use a lua table for the meat, `next` isn't likely to do anything useful.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: pairs() vs next() with userdata objects?

Post by eradicator »

quyxkh wrote:
Fri May 10, 2019 7:17 pm
for custom tables (i.e. userdata tables), where pretty much the entire point is not to use a lua table for the meat, `next` isn't likely to do anything useful.
Just for clarification, the issue originally was in my collection of generic table functions where i don't know what kind of table is coming in. I do appreciate all the detailed explanations though.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Post Reply

Return to “Modding help”