I found one topic that's about post hooking, but I don't think it's the same thing as I want to accomplish. topic i found
What I need is the following:
local someBoolean = false
function doSomething() -- this is the function used in __index in a proxy table
someBoolean = true
return aFunction -- this is function that we can NOT alter
end
I need to ble able to run the code "someBoolean = false" after the return... (yes, I know that's not supposed to happen :p) considering aFunction may contain other functions itself, I want someBoolean to be true for the entire scope of aFunction, but after that, it HAS to be turned back to false
I'm sorry if I didn't manage to explain it well enough. Copy pasting the relevant code of my actual project would be way too large, and I don't want to waste your time.
I've been stuck on this for a while now, and I just can't seem to figure it out...
(edit: I can't just put someBoolean = false after the function, because the function is actually an __index function on a proxy table)
edit: relevent piece of code. I hope it's a bit clear
local function objectProxyDelegate(t, key)
if not done then -- done = true when our object is fully initialised
return cls[key] -- cls is the class, newinst is the new instance (duh...)
end
print("trying to delegate " .. key)
if accessTable.public[key] then
print(key .. " passed the test")
objectScope = true
if accessTable.static[key] then -- static function. return the static one
return cls[key] -- we need to somehow set objectScope back to false after this, otherwise we'll keep overriding protected/private functions
else
return newinst[key]
end
elseif objectScope then
print("overridden protected/private")
return cls[key]
end
if accessTable.private[key] then
error ("This function is not visible. (private)", 2)
elseif accessTable.protected[key] then
error ("This function is not visible to an instance. (protected)", 2)
else
error ("The function " .. key .. " doesn't exiist in " .. newinst:getType(), 2) -- den deze...
end
end
Since you need to return a function (rather than evaluate a function) you can create a proxy for the aFunction and return that instead. Here's how it could work (with a bunch of code taken from the solution by Nicol Bolas):
local someBoolean = false
function doSomething(...) -- this is the function used in __index in a proxy table
someBoolean = true
-- Return a proxy function instead of aFunction
return function(...)
local rets = { aFunction(...) }
someBoolean = false
return table.unpack(rets)
end
end
You cannot execute code after a return statement. The correct answer is to call the function, catch the return values, set the variable, and then return the return values. For example:
local someBoolean = false
function doSomething(...) -- this is the function used in __index in a proxy table
someBoolean = true
local rets = { aFunction(...) } -- this is function that we can NOT alter
someBoolean = false
return table.unpack(rets)
end
Related
Eclipse is telling me that ')' is expected near '=', but surely that can't be right? This is my code:
Animator = Class{}
function Animator:init(statictilesize = true)
self.isTileSizeStatic = statictilesize
end
I'm so confused. I've only been using Lua for a month though, I'm more of a C++ / C# / Python guy. Maybe I'm missing something.
Okay, apparently I AM a total Lua Noob / spoiled C++ Python guy.
Lua doesn't allow that. Instead, inside of the init or constructor, put:
argument = argument or defaultValue
As in,
function Animator:init(statictilesize)
statictilesize = statictilesize or true
self.isTileSizeStatic = statictilesize
-- Yikes
end
Edit: I found a more stable solution, given that I require more arguments after the first.
function Animator:init(booleanstatictilesize, totalanimationstates, totalanimationframes)
if booleanstatictilesize ~= false then
self.isTileSizeStatic = true
else
self.isTileSizeStatic = false
end
end
Sort of hacked together type casting / checking. I could be wrong, I'm a noob at all this. I never had a formal programming education. I might sound like a total idiot.
Typically what seems to be done is to define your function like normal, and if the variables you want to be optional aren't set, you set them later, and redefine your function signature to look for a table:
Animator = Class{}
function Animator:init(args)
self.isTileSizeStatic = args.statictilesize ~= false
end
Later you call this function with this form of syntax:
Animator.init{statictilesize = false}
Both nil and false are the "falsey" conditions in Lua. All other conditions in Lua are truthy, including 0 and ''. So in order to get the functionality that when statictilesize is unset, it defaults to a true condition, you must check its inequality to false, as everything else will be true (including nil since nil is not false).
Please note that this would implicitly convert your argument into a bool
It's quite a bit different from Python.
See here for more details:
https://www.lua.org/pil/5.3.html
Additionally, if you want false to be part of the acceptable set of arguments passed to the function (or you simply don't want the argument implicitly converted to boolean) you can use the following syntax:
function Animator:init(args)
if args.statictilesize ~= nil then self.isTileSizeStatic = args.statictilesize else self.isTileSizeStatic = true end
end
I got this (very simplified) scenario while coding a port handling routine for a micro-controller.
3 files
file1:
table = {var1 = true, var2 = true, var 3 = false, var 4 = true}
function dosomething()
dosomething
--defines bools in table by whatever condition is present
end
file2: Actually a Menu. If an input is given the corresponding boolean in table is changed.
function selection()
selection = interprete_input()
invertVars(selection)
end
function invertVars(selection)
table.selection = not table.selection
end
file3: in the simplified scenario, only uses the bools#table to know it to operate for the given case or not. The indices are used as values as well. For example one entry in table could be ' ["ttyS0"] = true ' so I know the function whether should run for COM-Port ttyS0 or not
function needsVarsFromTable()
for v,k in pairs(table)
if k then
--the actual function uses true/false as indicator to know if to run
--for the entry of table or not.
the_actual_function_that_needs_v(v)
end
end
The Problem now is:
The Table contains 19 entries. 2 of them have to be static. They're false and can never be true. But in my script it's possible to make them true what will cause errors.
Unfortunately Lua doesn't bring static variables. How can I prevent them from be altered by other functions? These other functions still have to be able to read them.
I don't want to check for every var#Table if the reading function is allowed to alter, due performance issue.
PiL 13.4.5 provides an example of read-only table, read the whole chapter if you are not familiar with metatables and metamethods.
To protect the field "var2", a little modification to the code in the book can do it:
local t = {var1 = true, var2 = true, var3 = false, var4 = true}
function protect_field(t)
local proxy = {}
local mt = { -- create metatable
__index = t,
__newindex = function (t, k, v)
if k == 'var2' then
error("attempt to update var2 field")
else
rawset(t, k, v)
end
end
}
setmetatable(proxy, mt)
return proxy
end
t = protect_field(t)
Now it's legal to update field "var1":
t.var1 = false
But t.var2 = false will raise an error.
As a beginner in Lua, I am sorry if the answer on this is easy.
I was trying to call a function within a code, yet after 2 hours of searching I couldn't find the wanted results. (Maybe I use the wrong search query's?)
Example code
function Test123 ()
SayTest = True
if SayTest = True then
-- This Is where I want to call the function name Test123,
-- yet I can't seem to succeed in this since it is just
-- starting a new function
SystemNotice ( role, function)
end
end
This should be the result:
function Test123 ()
SayTest = True
if SayTest = True then
SystemNotice ( role, 'Test123')
end
end
If anyone can help me out, I would be thankful. If I am still being unclear, just tell me and I will try to describe it better. My excuses for my limited English.
In Lua functions are actually values. That means they do not really have a name, you can only assign them to a variable or table field, but since the value itself has no concept of its name, you can't retrieve it.
That said, with the debug library, you can do this:
function getfname()
return debug.traceback("", 2):match("in function '(.-)'");
end
function bar()
print(getfname())
end
bar(); -- prints bar
foo = bar;
foo() -- prints foo
knerf = {rab = bar};
knerf.rab() -- prints rab
Note that this only works with the default Lua error handler or one that returns the same or very similar output, however you can obviously modify the pattern to suit what you need.
Read this: I would not advise this solution for performance-intensive tasks. Both string matching and the traceback are not really suited for this. Also, obviously the debug library must be enabled so you can actually use the traceback function.
Your function declaration lacks anend.
function Test123 ()
end
Read the functions chapter from the Lua manual. Just for the record, your if will also need an end.
This is a construct that just goes against the Lua philosophy that functions are first class citizens:
a function is just another value, and as such it has no name.
A variable can be assigned a value, thus binding a function to a name.
But that name can change. or a function can have multiple names. Which one to pick?
A better solution would be creating an anonymous function with an upvalue (a closure) instead:
function genTest(name)
return function()
SayTest = true
if SayTest == true then
print ( 'role', name)
end
end
end
Test123 = genTest('Test123')
Test123()
foobar = Test123
foobar()
This creates a function with a bound local variable name (see PiL 6.1 ).
In Lua, is it possible to know which function has called the current function.
For instance
function a()
get_calling_function() --Should print function b
end
function b()
a()
end
Is something like this possible?
Does the debug library have such functionality?
You could use debug.traceback():
function a()
print(debug.traceback())
end
function b()
a()
end
b()
which would print:
stack traceback:
./test.lua:45: in function 'a'
./test.lua:50: in function 'b'
./test.lua:53: in main chunk
[C]: in ?
you can use debug.sethook() to set up a hook that gets called each time certain special events happen in lua. it can be useful for things like this.
local debugInfo = { caller = nil, callee = nil }
function hook()
local info = debug.getinfo(2)
if info == nil then
debugInfo.callee = nil
return
end
-- we only want to watch lua function calls (not C functions)
if info.what ~= "Lua" then
debugInfo.callee = "C function"
return
end
debugInfo.caller = debugInfo.callee
debugInfo.callee = info.name
end
debug.sethook(hook, "c")
function caller1()
if debugInfo.caller ~= nil and debugInfo.callee ~= nil then
msg = debugInfo.callee.. " was called by ".. debugInfo.caller.. "!"
print(msg)
end
end
function caller2()
caller1()
end
caller2()
this prints 'caller1 was called from caller2!'
debug.sethook can handle 3 different characters in the second parameter so you can let it know when to notify you. 'c' means call your hook function any time a function is called in lua, 'r' means call your hook function every time a function returns in lua, and 'l' means call your hook function whenever lua processes a new line of code.
you could set this up to build your own custom stack trace if you really wanted to, and you could also use debug.getlocal() within your hook to even try to work out what arguments were passed to your called function.
edit for lhf. this is actually a much simpler way of doing what you're asking, if you don't need to track this and just need to know the context of how the function was called.
function caller1()
local current_func = debug.getinfo(1)
local calling_func = debug.getinfo(2)
print(current_func.name.. " was called by ".. calling_func.name.. "!")
end
function caller2()
caller1()
end
I have simple function in VBA and I would need to check whether or not it has been successfully performed. I do not know VBA much, so I have no idea whether or not its possible. I want to do something like this: bool X=MyFunction().
I am using VBA in the QTP descriptive programming. This does not work:
Function A as Boolean
A=true
End Function
It says: Expected statement
But I cannot see any return type in my method etc.
function MyFunction() as Boolean
.....
.....
MyFunction = True 'worked
end function
dim a as boolean = MyFunction()
In VBA, you set a function's return value by assign to a variable with the same name as the function:
Function MyFunc() as Boolean
MyFunc = True
End Function
I suspect you may be using VBScript instead of VBA? If that's the case then VBScript doesn't state Type
this will work in VBScript
dim test,b
test = 1
b=false
msgbox ("Calling proc before function test=" & test)
msgbox("Calling proc before function b=" & b)
b = A(test)
msgbox ("Calling proc after function test=" & test)
msgbox("Calling proc after function b=" & b)
Function A(test)
test = test +1
A=true
End Function
or in your example
Function A()
A=true
End Function
There is no real way to check if a function worked in VBA. You must decide for yourself whether your function was successful. For example:
Function AFunction() as Boolean
on error goto 1
MyFunc = True
AFunction = True
Exit Function
1
AFunction = False
End Function
The above would let you know if the function failed. If it fails, it goes to the label '1' and then returns false, otherwise, it returns true.
If it isn't an 'error' you are looking for, then you must decide if the data returned or supplied is proper. One way of doing this is to return a specific value [error-code] which represents a failure.
Well if you have access to your function declaration, you can set a bool return type for it and return true or false depending on the execution.
Once your function returns a bool, your code will work.