Page 1 of 1
[0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Sun May 21, 2017 2:12 am
by sparr
"When called on an underground transport belt, this is the other end of the underground belt connection, or nil if none."
This changed at some point and now seems to return {} instead of nil for an unconnected underground input. Probably should just be fixed in the docs.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Mon May 22, 2017 1:23 am
by Rseding91
Thanks for noticing. It's now fixed for the next version of 0.15.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Mon May 22, 2017 1:47 am
by sparr
Can you say if you're updating the docs or switching the code back from {} to nil?
I already updated one mod to support either option, but I'd prefer to update others "correctly".
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Mon May 22, 2017 2:12 am
by Rseding91
Making it return what the docs say so "nil" or the entity for underground belts.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Tue May 23, 2017 7:31 pm
by dehook
Regardless of what the docs say, returning an empty collection generally allows for more concise client code than returning nil. This change has also broken at least two mods that used that more concise style.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Tue May 23, 2017 9:38 pm
by sparr
How long was this bug in effect? If it happened in maybe 0.15.9 then reverting it makes sense. If it happened in 0.14.0 and no one noticed until now but multiple mods have been written in the last year that use the {} behavior, then maybe {} is the better option.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Tue May 23, 2017 10:26 pm
by Rseding91
The electric pole result being a dictionary already means the return result must be inspected before it can be meaningfully used.
I don't really mind either way but it doesn't seem like one format or the other gives any advantage.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Tue May 23, 2017 10:53 pm
by Klonan
dehook wrote:Regardless of what the docs say, returning an empty collection generally allows for more concise client code than returning nil. This change has also broken at least two mods that used that more concise style.
I find that returning nil is generally far easier to work with,
is much simpler than
Rseding91 wrote:The electric pole result being a dictionary already means the return result must be inspected before it can be meaningfully used.
I don't really mind either way but it doesn't seem like one format or the other gives any advantage.
I would keep it as nil, as it is more consistent with the way most of the other API calls work
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Tue May 23, 2017 11:30 pm
by dehook
Klonan wrote:
I find that returning nil is generally far easier to work with,
The savings comes in something like this from an effected mod:
Code: Select all
for _, neighbour in pairs(entity.neighbours) do...
If entity.neighbours is an empty collection, then the for loop just doesn't do anything with no check for nil or empty required.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 1:29 am
by gheift
When it returns nil, just expand the code like this:
Code: Select all
for _, neighbour in pairs(entity.neighbours or {}) do...
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 4:38 am
by sparr
Apparently this bug existed for a while. Changing it back broke the following mods for me:
Orphan Finder
Fast Replace Underground Belts
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 4:55 am
by sparr
Code: Select all
local function has_neighbours(entity)
return not (entity == nil or entity.neighbours == nil or (#entity.neighbours == 0 and not entity.valid))
end
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 6:13 am
by Optera
Directly returning the other ug belt entity seems a bit counter intuitive to the the description.
neighbours :: dictionary string → array of LuaEntity or array of LuaEntity or LuaEntity [Read-only]
I would expect a dictionary containing the entity instead.
It should be:
neighbours :: → array of LuaEntity or array of LuaEntity or LuaEntity [Read-only]
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 8:26 am
by Nexela
I agree this "change" leads to some ugly hacks The way I thought of neighbours before this change was "Hey I want to visit the next(neighbours)
The plural s on neighbours makes my mind thing it is going to return a table with 0 or more items
before when using it on both pipes and undergrounds
if neighbours and #neighbours < 1 then ------
now I have to do some wonky stuff like compare types
if not neighbours or neighbours and not neighbours.type and #neighbours < 1 then -----
@optera
dictionary string → array of LuaEntity is for electrical poles {red = {}, copper = {}, green = {}}
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 10:32 am
by Narc
Nexela wrote:I agree this "change" leads to some ugly hacks [...] before when using it on both pipes and undergrounds
if neighbours and #neighbours < 1 then
Shouldn't that still work? I mean, 'if not neighbours' will be true if `if neighbours == nil` is true.
sparr wrote:Code: Select all
local function has_neighbours(entity)
return not (entity == nil or entity.neighbours == nil or (#entity.neighbours == 0 and not entity.valid))
end
I always like my sanity checks separate from the actual logic, so
Code: Select all
local function has_neighbours(entity)
if not entity or not entity.valid then return false end
if not entity.neighbours then return false end
return entity.neighbours < 1
end
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 10:57 am
by Nexela
Narc wrote:Code: Select all
local function has_neighbours(entity)
if not entity or not entity.valid then return false end
if not entity.neighbours then return false end
return entity.neighbours < 1
end
assuming your return is just missing the #
on an underground belt that will return 0 if the belt has neighbours since the neighbour is an entity
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 11:17 am
by Narc
Nexela wrote:assuming your return is just missing the #
Yup, sorry, untested code. It's also got the logic backward, and would fit "has_no_neighbours(entity)"
Nexela wrote:on an underground belt that will return 0 if the belt has neighbours since the neighbour is an entity [and entities have 0 array members, but still answer to #table]
Oh, yuck, I see what you mean. Might be a dictionary, might be an array, might be a single entity depending on the type. In fact, let's not forget: might raise an error if used on an entity that doesn't support it.
Code: Select all
local function has_neighbours(entity)
if not entity or not entity.valid then return false end
if not entity.neighbours then return false end
if entity.type == "underground-belt" then
return entity.neighbours and entity.neighbours.valid
elseif entity.type == "electric-pole" then
return #entity.neighbours.copper > 0 or #entity.neighbours.red > 0 or #entity.neighbours.green > 0
else
return #entity.neighbours > 0
end
end
Oh, and this will still raise an error if used on an entity that doesn't support .neighbours at all. I just don't even at this point.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 2:21 pm
by Nexela
I miss next(neighbours) already
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 2:37 pm
by Optera
sanity check for ug belts actually is really simplistic now:
Code: Select all
if entity.type == "underground-belt" and entity.neighbours then
My problem is like Nexela said, neighbours is plural indicating an array.
Also it returns 3 different things for the 3 different entity types it can be used on.
Re: [0.15] [Rseding91] LuaEntity:neighbours on underground belt returns {} not nil
Posted: Wed May 24, 2017 10:48 pm
by sparr
adding my opinion to the side that "neighbourS" ever returning a single entity, rather than a 1-entity array, makes for ugly code.