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.