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.
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.
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
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").
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
Related
I am confused by the following output:
local a = "string"
print(a.len) -- function: 0xc8a8f0
print(a.len(a)) -- 6
print(len(a))
--[[
/home/pi/test/wxlua/wxLua/ZeroBraneStudio/bin/linux/armhf/lua: /home/pi/Desktop/untitled.lua:4: attempt to call global 'len' (a nil value)
stack traceback:
/home/pi/Desktop/untitled.lua:4: in main chunk
[C]: ?
]]
What is the proper way to calculate a string length in Lua?
Thank you in advance,
You can use:
a = "string"
string.len(a)
Or:
a = "string"
a:len()
Or:
a = "string"
#a
EDIT: your original code is not idiomatic but is also working
> a = "string"
> a.len
function: 0000000065ba16e0
> a.len(a)
6
The string a is linked to a table (named metatable) containing all the methods, including len.
A method is just a function, taking the string as the first parameter.
function a.len (string) .... end
You can call this function, a.len("test") just like a normal function. Lua has a special syntax to make it easier to write. You can use this special syntax and write a:len(), it will be equivalent to a.len(a).
print(a.len) -- function: 0xc8a8f0
This prints a string representation of a.len which is a function value. All strings share a common metatable.
From Lua 5.4 Reference Manual: 6.4 String Manipulation:
The string library provides all its functions inside the table string.
It also sets a metatable for strings where the __index field points to
the string table. Therefore, you can use the string functions in
object-oriented style. For instance, string.byte(s,i) can be written
as s:byte(i).
So given that a is a string value, a.len actually refers to string.len
For the same reason
print(a.len(a))
is equivalent to print(string.len(a)) or print(a:len()). This time you called the function with argument a instead of printing its string representation so you print its return value which is the length of string a.
print(len(a))
on the other hand causes an error because you attempt to call a global nil value. len does not exist in your script. It has never been defined and is hence nil. Calling nil values doesn't make sense so Lua raises an error.
According to Lua 5.4 Reference Manual: 3.4.7 Length Operator
The length of a string is its number of bytes. (That is the usual
meaning of string length when each character is one byte.)
You can also call print(#a) to print a's length.
The length operator was introduced in Lua 5.1,
Without giving too much details, this sample snippet demonstrates the problem:
-- Add an extra predefined argument
function one_more_arg(...)
local args = {...}
return function()
print(table.unpack(args), "c")
end
end
local my_new_print = one_more_arg("a", "b")
my_new_print() -- "a c"
Apparently unpacking a table does not work in this scenario. Any ideas on how to make this work, ie print will receive "a", "b", "c"? I'm trying to avoid modifying args, unless it's the only way to achieve it.
When you place table.unpack() as an argument to function there should be no other arguments or it should be the last one. Otherwise only first value from table will be passed.
Lua always adjusts the number of results from a function to the
circumstances of the call. When we call a function as a statement, Lua
discards all of its results. When we use a call as an expression, Lua
keeps only the first result. We get all results only when the call is
the last (or the only) expression in a list of expressions. These
lists appear in four constructions in Lua: multiple assignment,
arguments to function calls, table constructors, and return
statements.
From http://www.lua.org/pil/5.1.html
So you can try to put unpack at the end if it is ok for you:
print("c", table.unpack(args))
Or modify args.
table.concat (list [, sep [, i [, j]]])
Given a list where all elements are strings or numbers, returns the string list[i]..sep..list[i+1] ยทยทยท sep..list[j]. The default value for sep is the empty string, the default for i is 1, and the default for j is #list. If i is greater than j, returns the empty string.
I am a newcomer to coding in general and I want to learn basic Lua scripting for my own hobby.
After working on a Lua script, the syntax all seems to be without error but I have come across one issue that I don't understand, I broke it down to this basic function:
{$lua}
ID1 = "10"
ID2 = "0"
if (ID1 ~= nil and ID1 == "10") then
writeInteger(ID2,"25")
end
print(ID2)
The issue is that the writeInteger does not seem to work at all, ID2 remains at value "0" while it should become "25".
Any help would be greatly appreciated.
This is not valid Lua, or at least it isn't valid vanilla (out-of-the-box) Lua, and since you have not specified anything else, there is not much we can do to help. I will assume writeInteger is a valid function (since your interpreter isn't complaining about a call to a nil value), but I don't think it works as you expect.
If you want to set the ID2 variable to 25, simply write:
ID2 = 25
Lua will convert the string type to an integer type automatically. You can run print(type(ID2)) to confirm this
If you are using cheat engine (as a quick google search suggests) the writeInteger function requires an address and a value.
function writeInteger(Address, Value): Boolean - Returns true on success.
I am not sure if ID2, a Lua variable, is a valid address, but I am sure that "25" is not an integer. You should remove the quotation marks to start, and since the function returns a boolean you can see if the function was successful by doing:
print(writeInteger(ID2, 25))
Lua uses pass by value for primitive types like numbers, booleans and strings. So if you pass a number to a function like writeInteger, it creates a local copy within the function. The function can alter this copy but it will have no effect on caller (of writeInteger in this case). I don't know how writeInteger is supposed to work but if you want to call a function which alters its argument you can create a table and pass that. Tables are still passed by value but the "value" of a table is its memory address (so in effect tables are passed by reference and you can alter the contents of a table by passing it to a function).
See more here
Function/variable scope (pass by value or reference?)
I am using LUA to create a table within a table, and am running into an issue. I need to also populate the NIL values that appear, but can not seem to get it right.
String being manipulated:
PatID = '07-26-27~L73F11341687Per^^^SCI^SP~N7N558300000Acc^'
for word in PatID:gmatch("[^\~w]+") do table.insert(PatIDTable,word) end
local _, PatIDCount = string.gsub(PatID,"~","")
PatIDTableB = {}
for i=1, PatIDCount+1 do
PatIDTableB[i] = {}
end
for j=1, #PatIDTable do
for word in PatIDTable[j]:gmatch("[^\^]+") do
table.insert(PatIDTableB[j], word)
end
end
This currently produces this output:
table
[1]=table
[1]='07-26-27'
[2]=table
[1]='L73F11341687Per'
[2]='SCI'
[3]='SP'
[3]=table
[1]='N7N558300000Acc'
But I need it to produce:
table
[1]=table
[1]='07-26-27'
[2]=table
[1]='L73F11341687Per'
[2]=''
[3]=''
[4]='SCI'
[5]='SP'
[3]=table
[1]='N7N558300000Acc'
[2]=''
EDIT:
I think I may have done a bad job explaining what it is I am looking for. It is not necessarily that I want the karats to be considered "NIL" or "empty", but rather, that they signify that a new string is to be started.
They are, I guess for lack of a better explanation, position identifiers.
So, for example:
L73F11341687Per^^^SCI^SP
actually translates to:
1. L73F11341687Per
2.
3.
4. SCI
5. SP
If I were to have
L73F11341687Per^12ABC^^SCI^SP
Then the positions are:
1. L73F11341687Per
2. 12ABC
3.
4. SCI
5. SP
And in turn, the table would be:
table
[1]=table
[1]='07-26-27'
[2]=table
[1]='L73F11341687Per'
[2]='12ABC'
[3]=''
[4]='SCI'
[5]='SP'
[3]=table
[1]='N7N558300000Acc'
[2]=''
Hopefully this sheds a little more light on what I'm trying to do.
Now that we've cleared up what the question is about, here's the issue.
Your gmatch pattern will return all of the matching substrings in the given string. However, your gmatch pattern uses "+". That means "one or more", which therefore cannot match an empty string. If it encounters a ^ character, it just skips it.
But, if you just tried :gmatch("[^\^]*"), which allows empty matches, the problem is that it would effectively turn every ^ character into an empty match. Which is not what you want.
What you want is to eat the ^ at the end of a substring. But, if you try :gmatch("([^\^])\^"), you'll find that it won't return the last string. That's because the last string doesn't end with ^, so it isn't a valid match.
The closest you can get with gmatch is this pattern: "([^\^]*)\^?". This has the downside of putting an empty string at the end. However, you can just remove that easily enough, since one will always be placed there.
local s0 = '07-26-27~L73F11341687Per^^^SCI^SP~N7N558300000Acc^'
local tt = {}
for s1 in (s0..'~'):gmatch'(.-)~' do
local t = {}
for s2 in (s1..'^'):gmatch'(.-)^' do
table.insert(t, s2)
end
table.insert(tt, t)
end
What's (in simple terms) the difference between setting a binding (LET) and symbols (=variables) in common lisp?
Symbols and variables are two very different kinds of entities. Symbol is a name of something; variable is a container for a value. Variable can be named by a symbol.
Binding is an association between a symbol and a variable; when binding is in effect, you can refer to a variable by its name. let form creates such a binding.
(let ((a 1))) sets the value of a to 1 until the point where the closing bracket which matches the opening bracket before the let is reached, at which point a reverts to whatever it's previous value was (or becomes undefined). You often see a let in the body of a function where you require local variables which need to go out of scope at the end of the function, so you would use a let there.
(setf a 1) sets a to 1 and assumes that either a has been previously defined (whether by defparameter, defvariable or let) or that a is a new special variable that needs a value.
It's a bit more complicated than that but I'm not sure i have the lisp chops to explain it.