20

What is the proper way to make a conditional which checks of something is or is not empty in Lua? if x == "" and f x ~= "" does not seem to work.

Village
  • 22,513
  • 46
  • 122
  • 163
  • Empty meaning, there is nothing typed in it. – Village Apr 26 '12 at 08:57
  • 2
    You can't "type" values into variables. Can you give a more precise definition? Because a variable that holds the `""` string isn't "empty". It has a string. Namely `""`. Which is a valid string. And therefore not nothing. – Nicol Bolas Apr 26 '12 at 09:08
  • Okay, then my meaning of empty is `""`. – Village Apr 26 '12 at 09:11
  • Then in what way doesn't your code work? `x = ""; if x == "" then print("empty"); else print("not empty"); end` is valid Lua code. And it will always print "empty". Is your problem that it ceases to work when you don't have the `x = ""` part? Or, to put it another way, just because *you* think `""` means empty doesn't mean *Lua* does. – Nicol Bolas Apr 26 '12 at 09:16
  • Provide us with some context; are you setting the value to `""` at any time? Are you reading the value from input? Is this a value returned by a library? It'll clarify to us what you mean by "empty" (a very subjective term) hence allowing us to help you more effectively. – Deco Apr 27 '12 at 17:15
  • I am using Lua inside ConTeXt. The value is empty, e.g., `\macro{}`. – Village Apr 27 '12 at 21:35

4 Answers4

17

Lua is a dynamically type-based language.
Any variable can hold one of the following types: nil, boolean, number, string, table, function, thread, or userdata.
Any variable in a table (including _G, the table where globals reside) without a value gives a value of nil when indexed. When you set a table variable to nil, it essentially "undeclares" it (removing the entry from memory entirely).
When a local variable is declared, if it is not assigned immediately it is given a value of nil. Unlike table variable, when you set a local variable to nil, it does not "undeclare" it (it just has a value of nil).

In Lua, an empty string ("") is still a "value" - it's simply a string of size zero.

Deco
  • 5,112
  • 1
  • 16
  • 17
  • I think saying "_When you set a variable to nil, it essentially "undeclares" it_" is a bit inaccurate—`nil` is a true value except inside tables, so for instance, a local variable with a value `nil` still shadows variables in surrounding scopes... – snogglethorpe Apr 26 '12 at 21:59
  • You're absolutely right; that statement was aimed at table pairs, not at all variables in general. Answer's been modified to reflect this. – Deco Apr 27 '12 at 05:04
  • @snogglethorpe `if nil then print( "nil is true") else print( "nil is not true!") end` --> nil is not true! – handle Aug 20 '15 at 15:37
  • @handle Heh... sorry, by "true value" I mean "real value", i.e. I was using "true" in the colloquial sense not in the Lua sense... ^^; – snogglethorpe Oct 19 '15 at 01:43
  • (I#m sorry, while this is a very old answer - I came here because it is root to a dupe. Reading the answer does not answer the question for me. Maybe the answer is technically hidden in it - for me as a nonprogrammer it talks about reasons & constraints and avoids a useful answer. Someone in the dupe was quick enough to post it there before closure. Just thought I could upvote here too) – Shegit Brahm Jun 08 '21 at 20:22
5

I recently ran across this problem as well. LuaSQL was returning empty strings if a database value was 'blank' (not null). A hacky approach, but here's how I solved it:

if (string.len(x) >= 1) then
    ...
end
3

I'm going to make an assumption that the OP means "how do you tell when a variable is unassigned".

Example:

local x

The variable x is "empty", it is initialized to "nil". (Not the text "nil", but an enumerated value that indicates that the variable is unassigned. In Lua that is defined as nil, in some other languages it is defined as NULL.)

Now assign x a value. Example:

x=""

Now x is not nil. Another example:

x=0

x is not nil.

Try running this code, it should make the situation clear to you.

local x
if x==nil then print("x is nil") end

x=0
if x==nil then print( "This line won't be written") end

x=""
if x==nil then print( "and this line won't be written") end

The first if statement will evaulate to true and the print statement will be called. The 2nd and 3rd if statements are false and the print statements will not be executed.

In conclusion, use "==nil" to check to see if a variable is "empty" (which is more properly said "nil").

Scott
  • 789
  • 6
  • 7
1

You probably have spaces, newlines or other non-visible characters in your string. So you think it is "empty", but it isn't. This typically happens when you are taking input from the user, and has to type "enter" to finish - the "enter" ends up in the string.

What you need is a function that tells you whether the string is "blank" - either empty, or a list of spaces/tabs/newlines. Here's one way to do it:

function isBlank(x)
  return not not tostring(x):find("^%s*$")
end

Usage:

if isBlank(x) then
  -- ...
end
kikito
  • 51,734
  • 32
  • 149
  • 189
  • 2
    thats quite inefficient; `not not string.find(x,"^%s*$")` – daurnimator Apr 26 '12 at 13:19
  • Well, your version is definitively (once you include the ommited tostring call). I'm not so sure it is significantly faster. Why do you think that? – kikito Apr 26 '12 at 13:49
  • `string.gsub` would allocate a lot of memory for that operation (a new string that's resized several times, one or two buffers for replacements) compared to `string.find`. – Deco Apr 27 '12 at 05:09
  • You are right. I was thinking in term of speed execution, not memory. I've updated my answer with your suggestion. – kikito Apr 27 '12 at 06:48
  • 1
    not not? Am I missing something or is this just a typo. Remove "not not" and it still works yet is much easier to read. – Leif Högberg May 09 '14 at 08:20
  • 2
    `not not` is a common idiom which means "transform into a boolean" in Lua. I don't use it often, but since the OP seems to be new to Lua, I figured he'd be less confused by a function that returns either `true` or `false`. Besides, `string.find` returns multiple values, which might have some side effects and catch you off-guard when you're new to the language. `not not` takes care of all that. – kikito May 09 '14 at 10:27
  • Isn't <> have the same meaning? – Bulat Nov 13 '16 at 04:14
  • local xd = " " Function is named isBlank which means that for xd it should return true. not tostring(x):find("^%s*$") would return false for an empty string. That's why there is not not. That is what the answerer was refering to, while find returns different values by default. – DreTaX Sep 21 '19 at 12:44