Reputation: 2929
In Lua is it possible to replace a local function from within itself? For example:
local function emptyFunction(arg)
return
end
local function exampleFunction(arg)
local result, err = io.open("/tmp/BadFile","w")
if result == nil then
print(err)
exampleFunction = emptyFunction
return
end
io.close(result)
end
Upvotes: 3
Views: 10787
Reputation: 178984
To redefine a function within the function itself, you need a reference to the function in a variable that has already been declared before the variable is assigned a reference to the function.
First example -- how not to do it -- does not work because "fx" is not in scope inside fx, as intuition suggests (to me) it would not be.
Frankly, I don't know how to precisely describe what "fx" inside the function represents -- but it seems to be a global variable that is in a scope that is somehow "more global than a 'global local' declaration."
In the global space, I always assumed these two were equivalent:
foo = 'bar';
local foo = 'bar';
Precisely speaking, they apparently are not genuinely equivalent, if you have a way of accessing both. This first example does exactly that, and here's why:
When you do this...
local myfunc = function () ...
... what are you actually doing?
You're first declaring an anonymous function, and second declaring "myfunc" and third setting "myfunc" as a reference to the anonymous function you just created. Until the moment the function begins to exist, "local myfunc" does not yet exist, because the statement that declares it hasn't actually been executed yet. (At least, that's how I perceive it.)
Here's the non-working version that illustrates this:
local fx = function ()
print(fx);
print("inside the original fx")
fx = function() print "I was redefined" end
end
function f2()
print("f2")
f2 = fx
end
f = f2
print(fx);
fx(); fx(); f2(); f2() f();
function: 0x21a6140 -- original "fx" ref is in "global local fx"
nil -- inner "fx" -- NOT set on first iteration, so it
inside the original fx -- can't be the same varliable
function: 0x21a6510 -- now it's set, but to new function,
inside the original fx -- but the "global local fx" does not contain our new function
f2
function: 0x21a6510
inside the original fx
f2
Second example, we declare local fx first, and then set it to a reference to the function. There are no other changes.
local fx; -- declare before assignment
fx = function ()
print(fx);
print("inside the original fx")
fx = function() print "I was redefined" end
end
function f2()
print("f2")
f2 = fx
end
f = f2
print(fx);
fx(); fx(); f2(); f2() f();
function: 0x2188e50 -- original function
function: 0x2188e50 -- same reference, so this one *is* in scope
inside the original fx
I was redefined -- and redefining it works exactly as expected
f2
I was redefined
f2
So, yes, there is a way. You need a global local variable that is declared, and subsequently you need to set that to a reference to the function so that it is in scope in the function that tries to redefine it.
In a similar way, the f2
function can't redefine itself. It only redefines what f2
means, inside f2
while f2()
is running.
Upvotes: 2
Reputation: 1407
Nothing prevents you from doing so. Local or not function name in Lua is actually variable name which points to function itself. So there is no any difference between
local function f1()
...
end
and
local f1 = function()
...
end
In both cases f1
is in scope of function body.
However, such replace won't change no any external references
function f1()
print("f1")
end
function f2()
print("f2")
f2 = f1
end
f = f2
f1(); f2(); f2() f();
will lead to output
f1
f2
f1
f2
Note, that if you add local
keyword to declarations - nothing changes
Upvotes: 1