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?)
Related
I got a simple code like:
table = {}
print(table.."hello")
then got a error like the title. I know i need to use tostring(table) to fix it . Why table or other types can't convert to string to concatenate a String automatically except number type ?
print(table) is available But print(table.."hello") is not .
Does lua have some rules?
Thanks you.
Why table or other types can't convert to string to concatenate a String automatically except number type?
This is a deliberate choice made by the Lua language designers. Strings and numbers are coerced: Every operation that expects a string will also accept a number and tostring it; every operation that expects a number will also accept a string and tonumber it.
Coercion is an operation applied to strings. Numbers will be tostringed. Any other type won't. For other primitive types like bools and nils this is somewhat questionable, since they can be converted to string without issue. For tables it's reasonable though since they are a reference type.
Unlike other languages which make such decisions for you, Lua is highly metaprogrammable: You can simply override the decision! In this case, metatables are the solution, specifically the __concat metamethod which gets called if concatenation (..) is applied to two values of which one has the metamethod (and is neither a string or number):
table = setmetatable({}, {
__concat = function(left, right)
if type(left) == "string" then
return left .. tostring(right)
end
return tostring(left) .. tostring(right)
end
})
print(table .. "hello") -- hellotable: 0x563eb139bea0
You could even extend this to primitive types (nils, booleans), some other reference types (functions, coroutines) using debug.setmetatable, but I'd advise against this.
The declaration of table = {} destroying the table library
The datatype table is not a string or number so concat with .. must fail
Try this instead...
mytab = {}
table.insert(mytab, "hello")
print(table.concat(mytab))
For the table library functions look: https://www.lua.org/manual/5.4/manual.html#6.6
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,
As I remembered 'tick' from FIG-Forth, it could be used without abortion when a word wasn't in the wordlist:
' the_word
gave a reference to the word if it was in the word-list and gave 'false' otherwise.
Is it possible to construct something like that in ANS Forth to be used with [if], [then] and [else]?
I guess something like this:
: tick ( a u -- xt|f ) bl word find 0= if drop 0 then ;
The FIG-Forth document says:
Leaves the parameter field address of dictionary word nnnn. As a
compiler directive, executes in a colon-definition to compile the
address as a literal. If the word is not found after a search of
CONTEXT and CURRENT, an appropriate error message is given.
Although it is entirely possible the version of FIG-Forth you where using did not abide by the standard, and returned false.
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
In my lua script I need to call a function which takes an arbritary number of arguments with, well, an arbitrary number of arguments…
I am building up my arguments as a table as I cant know how many arguments there will be.
Sample code:
local result = call.someFunc();
local arguments = {}
for k,v in pairs(result) do
table.insert(arguments, v.name)
end
-- here I would like to somehow pass the whole table and each item in the table
-- is then passed as a single argument to "someOtherFunc"
call.someOtherFunc(arguments[1], arguments[2], arguments[3] ....)
I am pretty new to lua, in PHP e. g. I would use call_user_func_array – is there something similiar in lua?
foo(unpack(arguments)) is equivalent to foo(arguments[1], arguments[2], ...).
The long answer can be found on the Lua Users' Wiki.
This covers everything including trailing nil arguments.
Just pass the table as the argument. No need to split it up into single arguments, just have the function loop through the table.