This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Creator's profile picture

How do I know if ... is nil or not?

Started by Creator, 13 May 2015 - 01:37 PM
Creator #1
Posted 13 May 2015 - 03:37 PM
Hi folks,

I've been having trouble with a program. The problem is that I don't know how to detect if … is nil.

For example

function wow(much,...)
    do something
end
option 1:
wow("hey","bla","bla","bla","bla")
option 2:
wow("hey")

In option 1, … should not be nil.

In option 2, it should.

How do I know?
CrazedProgrammer #2
Posted 13 May 2015 - 03:44 PM

local args = {...}
if #args == 0 then
-- ... is nil
else
-- ... contains something
end
Edited on 13 May 2015 - 01:45 PM
Creator #3
Posted 13 May 2015 - 03:45 PM
Shoot, that was real dumb of me. Scumbag brain. Anyways, thanks.
CrazedProgrammer #4
Posted 13 May 2015 - 03:48 PM
No problem :P/>
SquidDev #5
Posted 13 May 2015 - 03:57 PM
I was bored.


local function isNil(...)
	local len = select('#', ...)
	if len == 0 then return true end

	local t = {...}
	for k = 1, len do
		if t[k] ~= nil then return false end
	end
	return true
end

print(isNil(1, 2, 3)) -- Not nil
print(isNil(nil, 1, 2, 3)) -- Not nil
print(isNil(nil, nil)) -- Nil
print(isNil()) -- Nil

I thought they it would be functionally different to #({…}) == 0, but #({nil, 1, 2, 3}) == 4. Well, you learn something new everyday!
Edited on 13 May 2015 - 01:59 PM
Creator #6
Posted 13 May 2015 - 04:07 PM
This topic is getting out of control.
Bomb Bloke #7
Posted 14 May 2015 - 01:06 AM
You can also just do this sort of thing:

function wow(much,...)
    print(#arg)
end
--option 1:
wow("hey","bla","bla","bla","bla")  -- Prints 4
--option 2:
wow("hey")  -- Prints 0
ElvishJerricco #8
Posted 14 May 2015 - 03:10 AM
Alternatively,

function wow(much, ...)
    if not (...) then
        print("At least the first element is nil")
    end
end
Putting parentheses around a vararg thing like a function return or … will treat it like only the first value in the list.

But Squid's is better, since it correctly figures out the length of … using facilities that aren't possible in pure Lua.
Bomb Bloke #9
Posted 14 May 2015 - 03:30 AM
But Squid's is better, since it correctly figures out the length of … using facilities that aren't possible in pure Lua.

I'm not sure what you mean… are you saying select() (or table.maxn(), for that matter) aren't Lua functions?
ElvishJerricco #10
Posted 14 May 2015 - 03:58 AM
It's not possible to implement select's length function in pure Lua. Let me show you an attempt so I can point out the flaw.

I should clarify, it's not possible in CC's LuaJ, at least. The following works in ordinary C-based Lua, but not on CC.


function length(...)
    return #({...})
end

Issue here, is that the table constructed by {…} will cut off at the first nil. So length("a", nil, "b") will return 1.

A recursive attempt yields the same result.


function length(first, ...)
    if first == nil then
        return 0
    else
        return length(...) + 1
    end
end

Here, we again cut off at the first nil. You could argue that you can just check the second parameter, but what if the call was length(nil, nil, nil)? The result should be three but we get 0.

So in LuaJ, the only way to get the expected result of length(nil, nil, nil) is this


function length(...)
    return select("#", ...)
end

Because select isn't implemented in Lua. It's in Java, so it has facilities to actually check the length of the arguments array.
Bomb Bloke #11
Posted 14 May 2015 - 04:34 AM
… #({…}) is also implemented in Java, but I guess I see what you mean. :P/> Interesting to know that select() can figure out the length even if there's no non-nil arguments. I feel like I should be able to think up a use for that… Though playing around in repl.it, I find it rather hard to preserve a set of nils when passing them between functions…

Still, it seems like a rather round-about route to determine if there's an argument provided or not. If I wanted the exact functionality of SquidDev's isNil() function, I'd do:

local function isNil(...)
        return table.maxn(arg) == 0
end
SquidDev #12
Posted 14 May 2015 - 09:05 AM
I'm just going to point out the main point of my post:

I was bored.

Gotta agree, this topic has got out of control. Sorry. Also, thanks Bomb Bloke for reminding me about arg, it is one of those things I always forget.
Bomb Bloke #13
Posted 14 May 2015 - 11:15 AM
Nothing wrong with being bored. People only ever do or say anything interesting out of boredom!