Accessing array elements in lua does not work well - lua

When I have a function that return multiple values I can either store them in seperat values or use the {} operator to get an array.
To access the values I can either define a variable to store the value or access the array via array[index]. When using a temp var to print the value I code:
function myTest()
return "abc", "def", "geh";
end
a = {myTest()};
v = a[2];
print(v);
which works very well. But when printing the "indexed array converted return value" from the function with
function myTest2()
return "abc", "def", "geh";
end
print({myFunction2()}[2]);
nothing gets printed.
Can someone explain me why?

The form:
{myFunction2()}[2]
is not syntactically valid. I get an unexpected symbol error for that.
You can write it like:
({myFunction2()})[2]
and then it works as expected.

Just don't. When you want to immediately access the Nth return value of a function, use (select(N, ...)), which does not create a new table (and thus creates less work for the GC)
function myTest2()
return "abc", "def", "geh";
end
print( (select(2, myFunction2())) );
Note that enclosing a list of values in () truncates it to the first value; this is necessary because select(N, ...) returns the Nth and all following values. (select(N, ...)) returns only the Nth value.

Related

how can I do this with the variables in lua?

How can I make the 2 "print" give me true?
Code:
Config = {}
Config.option1.general = true
Config.option2.general = false
print(Config.option1.general)
print('Config.'..'option1'..'.general')
Output:
true
Config.option1.general
Excuse me for my ignorance
The objective was to create a function to which you give the option and execute a code with the variables of the corresponding list.
Just create a function that takes as input an option string, and use the string as a key into the Config table:
function getOption (opt)
return Config[opt].general
end
Then you can use the returned value however you like:
> getOption('option1')
true
> print(getOption('option1'))
true
> if (getOption('option1')) then print 'Yay!' else print 'Aw...' end
Yay!
If you want to live dangerously, you can use load to run a chunk of code from a string. Using this feature with user input is begging for security problems, though.
Just write a function that takes a string specifying the option, and use that input to fashion a string representing the chunk. The load function returns a function that has the chunk as its body, so you will need to call that returned function to get the result from the chunk:
function getOption (opt)
local cmd = 'Config.' .. opt .. '.general'
return load('return ' .. cmd)()
end
With getOption('option1'), the cmd string becomes 'Config.option1.general', and this is concatenated with 'return ' to create the chunk 'return Config.option1.general' which is passed to load. The statement load('return Config.option1.general')() calls the function returned by load, and the returned value is returned again from the getOption function.
Sample interaction:
> getOption('option1')
true
> getOption('option2')
false
the first print is collecting a variable and therefore displaying the value of this variable
the second print is already collecting a STRING. A string is a set of characters, they represent only text, and therefore that text will be displayed
for example, imagine that we have a variable test = true
if you do print(test), the value of the variable will be displayed, that is, true. Now, if you get print("test"), the "" means that we are talking about a text "test", not the variable test, so test will be displayed instead of true.
Note that in the second print, 2 dots .. are used, this is called CONCATENATION, it is when we join two or more strings, that is, two or more texts in one
For this reason there is no way you print true on the second print, because you are collecting a STRING with the name of the variable, and not the variable itself

Can I select value from table based on function input?

I would like to know if it's possible to select a value from a table, based on the argument of a function.
I've tried setting the value statically, and that returns the value. I would just like to do it using function arguments.
function CheckWeapon(ped, attachment)
for k,v in pairs(weapons)do
if GetHashKey(k) == GetSelectedPedWeapon(ped) then
print(v.attachment)
return v.attachment -- This needs to be based on the
-- argument "attachment"
end
end
return false
end
I would expect that if I supplied the argument "silencer" to this function, I would receive the corresponding value for silencer in the table. Instead it's nil. If I type return v.silencer manually, it works though.
In Lua you can index a table 2 ways.
As you have done you can use . such as sometable.key
but this is just syntactic sugar for the other method of indexing, sometable["key"]
both of these use the string key to index the table.
your code could look like:
function CheckWeapon(ped, key)-- where key is a string ie: "attachment"
for k,v in pairs(weapons)do
if GetHashKey(k) == GetSelectedPedWeapon(ped) then
print(v[key])
return v[key]
end
end
return false
end
using the sometable["key"] option also allows for keys that could not be accessed with . such as
sometable["my key"] -- note the space
sometable["1st_key"] -- note it begins with a number

Google Dart : How does .where() function work?

var fruits = ['apples', 'oranges', 'bananas'];
fruits[0]; // apples
fruits.add('pears');
fruits.length == 4;
fruits.where((f) => f.startsWith('a')).toList();
The example in the documentation shows the above.
I dont really understand the documentation of the method either.
https://api.dartlang.org/stable/1.21.1/dart-collection/IterableMixin/where.html
I currently see a lambda function as a parameter inside where, with where having the argument f. What is f though? Im a bit confused.
It would be great if I could see a working example. As it stands now I dont really get it. I dont know how it works or what it really does apart from that it acts as some sort of filter.
Is an anonymous function and f is the parameter it accepts
(f) => f.startsWith('a')
where(...) calls that passed function for each element in fruits and returns an iterable that only emits the values where the function returned true
where(...) is lazy, therefore the iteration and call of the passed function will only happen when the result is actually accessed, like with .toList().
DartPad example
update
"anonymous" means the function has no name in contrary to a named function like
myFilter(f) => f.startsWith('a');
main() {
fruits.where(myFilter).toList();
}
also
myFilter(f) => f.startsWith('a');
is just a shorter form of
myFilter(f) {
return f.startsWith('a');
}

List of functions

Following definitions print already the result of the functions in the table:
function plus1(zahl) print(zahl+1) end
function plus2(zahl) print(zahl+2) end
function plus3(zahl) print(zahl+3) end
-- already prints out 6,5,10
local tfunc={plus1(5),plus2(3),plus3(7)}
how can I avoid this?
how can I iterate through the functions with given parameters in the table? I would like to call the functions like:
tfunc[1]
to print out 6. But it does not work.
#pschulz, thanks to show me the way :
local tfunc = {{plus1,5},{plus2,3},{plus3,7}}
tfunc[i][1](tfunc[i][2])
allows to iterate with index i through the different functions with different args. The trick is tables with function name and args inside the table.
In you table, you are currently storing nothing (or three nil). The table takes the return value of the function and since you are returning nothing, it gets nil.
What you have to do is store functions:
local tfunc = {
plus1,
plus2,
plus3
}
No you can call your functions like this:
tfunc[1](5)
On iterating: If i understand correctly, you want to do the following:
local tfunc = {
plus1,
plus2,
plus3
}
local tvalues = { 5, 3, 7 }
for i, func in ipairs(tfunc) do
func(tvalues[i])
end
So you have to save your values in another table. There are more elegant ways to do this, i suggest you have a reading on closures.
local tfunc={plus1(5),plus2(3),plus3(7)}
Here you call the functions inside the table constructor.
So once you create your table you will print those values. As your function does not return anything tfunc remains empty.
You can either store the function call as a string and let Lua execute that string or you can save the function in the table without calling it. Then you need some way to get the function parameter zahl into your function call.
To me what you want to do makes no sense.
If you want to call it like tfunc[1] it will always print 6. So why not just call print(6)?
If you want to add 3 to a number you want to print, just call print(number + 3) e.g.
Your code will remain more readable and easier to understand if you don't move simple arrithmetics into an extra function.

How to set name for function which is in the table

For example, I have a table
table.insert( t, 1, function()
print ("rock");
end );
Is there any way to get function name from this table. I know that I can store name like a key, but what if I want to keep numeric index and also I want to know function name?
Is there any way to do it?
Thanks, on advance.
Say you have this code:
t = {}
x = 5
table.insert(t, 1, x)
t would then be {[1] = 5}. "5" is just a number - it has no name, and isn't associated with the variable "x"; it's a value.
In Lua, functions are treated exactly the same way, as values:
t = {}
x = function() print("test! :D") end
table.insert(t, 1, x)
The value of x is not associated with x in any way, shape, or form. If you want to manually name a function, you can do it by wrapping the function in a table, for example:
t = {}
x = function() print("test! :D") end
table.insert(t, 1, {
name = "MyFunctionName",
func = x
})
That is how you would do it!
...unless..
..you break the rules!
When Lua was developed, the developers realised that the anonymous nature of functions would make productive error messages difficult to produce, if not impossible.
The best thing you'd see would be:
stdin: some error!
stdin: in function 'unknown'
stdin: in function 'unknown'
So, they made it so that when Lua code was parsed, it would record some debug information, to make life easier. To access this information from Lua itself, the debug library is provided.
Be very careful with functions in this library.
You should exert care when using this library. The functions provided here should be used exclusively for debugging and similar tasks, such as profiling. Please resist the temptation to use them as a usual programming tool: they can be very slow. Moreover, several of these functions violate some assumptions about Lua code (e.g., that variables local to a function cannot be accessed from outside or that userdata metatables cannot be changed by Lua code) and therefore can compromise otherwise secure code.
To achieve your desired effect, you must use the debug.getinfo function; an example:
x = function()
print("test!")
print(debug.getinfo(1, "n").name)
end
x() -- prints "test!" followed by "x"
Unfortunately, the form of debug.getinfo that operates directly on a function doesn't fill the name argument (debug.getinfo(x, "n").name == nil) and the version above requires you to run the function.
It seems hopeless!
...unless..
..you really break the rules.
The debug.sethook function allows you to interrupt running Lua code at certain events, and even change things while it's all happening. This, combined with coroutines, allows you to do some interestingly hacky stuff.
Here is an implementation of debug.getfuncname:
function debug.getfuncname(f)
--[[If name found, returns
name source line
If name not found, returns
nil source line
If error, returns
nil nil error
]]
if type(f) == "function" then
local info = debug.getinfo(f, "S")
if not info or not info.what then
return nil, nil, "Invalid function"
elseif info.what == "C" then
-- cannot be called on C functions, as they would execute!
return nil, nil, "C function"
end
--[[Deep magic, look away!]]
local co = coroutine.create(f)
local name, source, linedefined
debug.sethook(co, function(event, line)
local info = debug.getinfo(2, "Sn")
name = info.namewhat ~= "" and info.name or nil
source, linedefined = info.short_src, info.linedefined
coroutine.yield() -- prevent function from executing code
end, "c")
coroutine.resume(co)
return name, source, linedefined
end
return nil, nil, "Not a function"
end
Example usage:
function test()
print("If this prints, stuff went really wrong!")
end
print("Name = ", debug.getfuncname(test))
This function isn't very reliable - it works sometimes, and doesn't others. The debug library is very touchy, so it's to be expected.
Note that you should never use this for actual release code! Only for debugging!
The most extreme case that is still acceptable is logging errors on piece of released software, to help the developer fix issues. No vital code should depend on functions from the debug library.
Good luck!
The function hasn't got any name. If you want you can assign it to a named variable:
theFunction = t[1]
-- Call it:
theFunction()
If what you want is storing a named function to the table, define it beforehand and use its name to store it:
theFunction = function()
print ("rock");
end
table.insert(t, 1, theFunction)
If this is not what you meant, give more details; for example how you would like to access the function. You're question is a bit misty.
The thing is table.insert considers the table as a sequence, only with numeric keys.
If you want to be able to call the function as t.fun() you'll have to use the table as an associative array and hence use a string as key. (BTW any type except nil or NaN are allowed as key)
t={}
t['MyFun']=function print'foo' end
t.myFun() -- uses syntactic sugar for string keys that are valid identifiers.
You might also notice that functions are passed by reference. So all functions are actually anonymous, and are just stored as a value to a certain key or variable.
You can store the names in a separate table.
functions = {}
functionNames = {}
function addFunction(f, name)
table.insert(functions, f)
functionNames[name] = f
end
To get the function, you can use the index. Once you have the function, you can get its name from function_names:
f = functions[3]
name = functionNames[f]
Good luck!

Resources