How to create a function with variable parameters just like table.insert()? - lua

I know I can use function(a, b, ...) to solve variable parameters problems. But how can I do if I want to create a function like table.insert (table, [pos,] value) ?
Of cause, not in the following way:
function (table, pos, value)
if value == nil then
pos = value
value = nil
end
-- do something
end

Lua does not have function overloading or typechecking of arguments, if needed those should be implemented by the one needing.
Conveying the usage of your function is also up to you.
If you are not satisfied with your provided snippet, you can rewrite it in other manners for example :
function(arg1,arg2,arg3)
tab=arg1
if not arg3 then
value=arg2
index=#tab+1
else
assert(type(arg2)=='numer',"bad argument #2 to 'insert' (number expected, got table)")
value=arg3
index=arg2
end
table.insert(tab,index,value)
end
or:
f2=function(a,b)
--do smth
end
f3=function(a,b,c) end
f=function(...)
args={...}
nargin=#args
if nargin==2 then
f2(args[1],args[2]) --one way to use varied arguments
elseif nargin==3 then
f3(...) --other one
else error("wrong number of arguments")
end
end
I don't recommend you making functions with optional middle positional arguments though. At least not in a language without compile time type check, and even in those as well.
If you really want optional arguments, put them in the table:
function(args)
tab=args.table
index=args.index or #tab+1
value=args.value
--other arguments, options and associated logic here
table.insert(tab,index,value)
end

Related

Trying to understand Custom Iterators

im trying to understand the iterators, in many examples I founf something like this:
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
function squares(iteratorMaxCount)
return square,iteratorMaxCount,0 // why not return square(iteratorMAxCount,0)????
end
for i,n in squares(3)
do
print(i,n)
end
First I dont understand the line I comment, and I dont find an easy example of how to do a Stateful Iterator and a Stateless iterator. Can anybody help me? thanks
From Lua Reference Manual 3.3.5:
A for statement like
for var_1, ···, var_n in explist do block end is equivalent to the code:
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
if var_1 == nil then break end
var = var_1
block
end
end Note the following:
explist is evaluated only once. Its results are an iterator function,
a state, and an initial value for the first iterator variable. f, s,
and var are invisible variables. The names are here for explanatory
purposes only. You can use break to exit a for loop. The loop
variables var_i are local to the loop; you cannot use their values
after the for ends. If you need these values, then assign them to
other variables before breaking or exiting the loop.
So squares() has to return a function (square) a state (iteratorMaxCount) and an initial value (0) in order to work with a generic for loop.
Read the reference manual, Programming in Lua.

Dumping lua func with arguments

Is it possibly to dump the Lua table including function arguments?
If so, how can I do it?
I have managed to dump tables and function with addresses, but I haven't been able to figure out a way to get function args, i have tried different methods, but no luck.
So I want to receive them truth dumping tables and function plus args of the function.
Output should be something like this: Function JumpHigh(Player, height)
I don't know if it is even possible, but would be very handy.
Table only stores values.
If there's function stored in a table, then it's just a function body, there's no arguments. If arguments were applied, table would store only final result of that call.
Maybe you're talking about closure - function returned from other function, capturing some arguments from a top level function in a lexical closure? Then see debug.getupvalue() function to check closure's content.
Is this something what you're asking?
local function do_some_action(x,y)
return function()
print(x,y)
end
end
local t = {
func = do_some_action(123,478)
}
-- only function value printed
print "Table content:"
for k,v in pairs(t) do
print(k,v)
end
-- list function's upvalues, where captured arguments may be stored
print "Function's upvalues"
local i = 0
repeat
i = i + 1
local name, val = debug.getupvalue(t.func, i)
if name then
print(name, val)
end
until not name
Note that upvalues stored is not necessary an argument to a toplevel function. It might be some local variable, storing precomputed value for the inner function.
Also note that if script was precompiled into Lua bytecode with stripping debug info, then you won't get upvalues' names, those will be empty.

Lua - get table hex identifier

I want to know how to get the table hex id. I know that doing:
local some_var = {}
print (some_var)
the result is (for instance):
table: 0x21581c0
I want the hex without the table: string. I know that maybe some of you suggest me to make a regular expression (or something similar) to remove those chars, but I want to avoid that, and just get the 0x21581c0
Thanks
This is simpler and works for all types that are associated with pointers:
local function getId(t)
return string.format("%p", t)
end
print("string:", getId("hi"))
print("table:", getId({}))
print("userdata:", getId(io.stdin))
print("function:", getId(print))
print("number:", getId(1))
print("boolean:", getId(false))
print("nil:", getId(nil))
Result:
string: 0x0109f04638
table: 0x0109f0a270
userdata: 0x01098076c8
function: 0x0109806018
number: NULL
boolean: NULL
nil: NULL
In the standard implementation, there is the global 'print' variable that refers to a standard function that calls, through the global variable 'tostring', a standard function described here. The stanard 'tostring' function is the only way to retrieve the hexadecimal number it shows for a table.
Unfortunately, there is no configuration for either of the functions to do anything differently for all tables.
Nonetheless, there are several points for modification. You can create you own function and call that every time instead, or point either of the the global variables print or tostring to you own functions. Or, set a __tostring metamethod on each table you need tostring to return a different answer for. The advantage to this is it gets you the format you want with only one setup step. The disadvantage is that you have to set up each table.
local function simplifyTableToString(t)
local answer = tostring(t):gsub("table: ", "", 1)
local mt = getmetatable(t)
if not mt then
mt = {}
setmetatable(t, mt)
end
mt.__tostring = function() return answer end
end
local a = {}
local b = {}
print(a, b)
simplifyTableToString(a)
print(a, b)
Without complex patterns, you can just search for the first space, and grab the substring of what follows.
function get_mem_addr (object)
local str = tostring(object)
return str:sub(str:find(' ') + 1)
end
print(get_mem_addr({})) -- 0x109638
print(get_mem_addr(function () end)) -- 0x108cf8
This function will work with tables and functions, but expect errors if you pass it anything else.
Or you can use a little type checking:
function get_mem_addr (o)
return tostring(o):sub(type(o):len() + 3)
end
The table id stated by the OP is invalid in the version of Lua I am using (5.1 in Roblox). A valid ID is length 8, not 9 as in your example. Either way, just use string.sub to get the sub-string you are after.
string.sub(tostring({}), 8)
The reason is, 'table: ' is 7 characters long, so we take from index 8 through the end of the string which returns the hex value.

In Lua, is there a function that given a function, it returns its name as a string?

Sorry if this is too obvious, but I am a total newcomer to lua, and I can't find it in the reference.
Is there a NAME_OF_FUNCTION function in Lua, that given a function gives me its name so that I can index a table with it? Reason I want this is that I want to do something like this:
local M = {}
local function export(...)
for x in ...
M[NAME_OF_FUNCTION(x)] = x
end
end
local function fun1(...)
...
end
local function fun2(...)
...
end
.
.
.
export(fun1, fun2, ...)
return M
There simply is no such function. I guess there is no such function, as functions are first class citizens. So a function is just a value like any other, referenced to by variable. Hence the NAME_OF_FUNCTION function wouldn't be very useful, as the same function can have many variable pointing to it, or none.
You could emulate one for global functions, or functions in a table by looping through the table (arbitrary or _G), checking if the value equals x. If so you have found the function name.
a=function() print"fun a" end
b=function() print"fun b" end
t={
a=a,
c=b
}
function NameOfFunctionIn(fun,t) --returns the name of a function pointed to by fun in table t
for k,v in pairs(t) do
if v==fun then return k end
end
end
print(NameOfFunctionIn(a,t)) -- prints a, in t
print(NameOfFunctionIn(b,t)) -- prints c
print(NameOfFunctionIn(b,_G)) -- prints b, because b in the global table is b. Kind of a NOOP here really.
Another approach would be to wrap functions in a table, and have a metatable set up that calls the function, like this:
fun1={
fun=function(self,...)
print("Hello from "..self.name)
print("Arguments received:")
for k,v in pairs{...} do print(k,v) end
end,
name="fun1"
}
fun_mt={
__call=function(t,...)
t.fun(t,...)
end,
__tostring=function(t)
return t.name
end
}
setmetatable(fun1,fun_mt)
fun1('foo')
print(fun1) -- or print(tostring(fun1))
This will be a bit slower than using bare functions because of the metatable lookup. And it will not prevent anyone from changing the name of the function in the state, changing the name of the function in the table containing it, changing the function, etc etc, so it's not tamper proof. You could also strip the tables of just by indexing like fun1.fun which might be good if you export it as a module, but you loose the naming and other tricks you could put into the metatable.
Technically this is possible, here's an implementation of the export() function:
function export(...)
local env = getfenv(2);
local funcs = {...};
for i=1, select("#", ...) do
local func = funcs[i];
for local_index = 1, math.huge do
local local_name, local_value = debug.getlocal(2, local_index);
if not local_name then
break;
end
if local_value == func then
env[local_name] = local_value;
break;
end
end
end
return env;
end
It uses the debug API, would require some changes for Lua 5.2, and finally I don't necessarily endorse it as a good way to write modules, I'm just answering the question quite literally.
Try this:
http://pgl.yoyo.org/luai/i/tostring
tostring( x ) should hopefully be what you are looking for
If I am not wrong (and I probably will, because I actually never programmed in Lua, just read a bunch of papers and articles), internally there is already a table with function names (like locals and globals in Python), so you should be able to perform a reverse-lookup to see what key matches a function reference.
Anyway, just speculating.
But the fact is that looking at your code, you already know the name of the functions, so you are free to construct the table. If you want to be less error prone, it would be easier to use the name of the function to get the function reference (with eval or something like that) than the other way around.

Functions in a Table - Lua

I have a table that has multiple functions in it. I'm trying to write a single function that will go through and use all the functions by passing random information into it.
Methods = {}
insert functions into Methods Table
function Methods:Multi() if #self > 0
then .........................
I'm guessing i need a loop that goes through the entire table but I can't do #self because i need it to do each function multiple times. Not sure how to pass in random info to the function either. Any help would be appreciated
Your problem doesn't seem to be all that specific - you're likely going to need to define exactly what you want to happen in more detail in order to be able to implement a program for it. (Sort of like if you told me "I need a program that calculates a number" - I'd probably respond "okay, what number do you want it to calculate?"
Things to consider:
Exactly how many times do you want to call each function? Will this be the same for each function? Will it vary?
If the number of calls varies, what should determine this?
How exactly do you want to determine what parameters are passed? Their types/count? Their values?
A very basic starting framework might look like this:
Methods = {}
-- Insert functions into Methods table
for _,func in ipairs(Methods) do
for i=1,5 do
func()
end
end
which would call each function 5 times, albeit w/o arguments.
I modified the above suggestion to
function CallFuncs(times, funcs, ...)
while (times > 0) do
for _, func in pairs(funcs) do
func(...)
end
times = times - 1
end
end
Example usage:
t = {
function( n ) print( n ) end,
function( n ) print( #n ) end,
}
CallFuncs( 2, t, 'foo' )
yields
foo
3
foo
3
Try this:
function CallFuncs(times, funcs, ...)
for i=1,times do
for _, func in pairs(funcs) do
if type(...) == "table" then func(unpack(...)) else func(...) end
end
end
end
Usage:
local t = {
function(n) print(n) end,
function(n) print(n+1) end,
function(n) print(n+2) end
}
CallFuncs(3, t, 2)
This assumes all the functions in the table have more or less the same arguments.
Info:
The ... you see is lua's syntax for variable arguments (these are packed into a table and used as the last argument to the function), and the unpack function takes a table and multi-returns a series of values.
If you are asking for something to call a list of functions, I just typed this very small module for you (if you can even call it that).
-- No guarantees whether this will work.
function ExecFunc (fnctn,nTimes,Threaded,...)
local to_call = function ()
fnctn(...)
end
for x = 1,nTimes do
if Threaded then
coroutine.resume(coroutine.create(to_call))
else
to_call()
end
end
end
function ExecFuncs (Async,...)
-- All parts of ... should be tables {function f, number t[, table args]}
local funcInfo = {...}
for _,funcThing in pairs(funcInfo) do
local a = funcThing.args
if a then
ExecFunc(funcThing.f,funcThing.t,Async,unpack(a))
else
ExecFunc(funcThing.f,funcThing.t,Async)
end
end
end
-- These don't check for argument validity,
-- so you should either be careful with the arguments
-- or call these in protected mode (with pcall).
If I wasted my time with that, it was fun anyway, but after typing it I reread your question... You want something to iterate through a list of functions and pass a random number to each one.
function ExecuteWithRandomValues (func_list,async)
assert(type(func_list) == "table","Expected table.")
local passbacks = {}
local threads
if async then
threads = {}
end
for _,func in pairs(func_list) do
assert(type(func) == "function","Value [" .. _ .. "] is not a function.")
local toCall = function ()
local rnd = math.random(-math.huge,math.huge)
local out = func(rnd)
passbacks[_] = {input = rnd, output = out}
end
if async then
table.insert(threads,coroutine.create(toCall))
else
toCall()
end
end
if async then
for _,thread in pairs(threads) do
coroutine.resume(thread)
end
for _,thread in pairs(threads) do
while coroutine.status(thread) ~= "dead" do
end
end
end
return passbacks
end
-- Again, no guarantees this thing is free of errors.
-- There are better ways to run and check the statuses
-- of asynchronous threads, but this is fairly convenient.

Resources