The following Lua 4.0 script fails due to some of the variables being in an 'outer' scope. What are the different ways I can fix this? I would like to avoid putting things in the global scope completely if possible. Thanks.
function flokalAdd(iNx, iNy, iXmin, iSym, fEcc, bInside, fScale)
TWO_PI = 2 * PI;
iSx = 4;
iSy = 4;
function pow(fA, fB)
return fA^fB
end
function mag(fX, fY)
return dist(fX, fY, 0, 0)
end
function dist(fX1, fY1, fX2, fY2)
return sqrt(pow(fX2 - fX1, 2) + pow(fY2 - fY1, 2))
end
function norm()
local fY1 = 0;
local fX1 = 0;
local fX2 = exp(fX1) * cos(deg(fY1));
local fY2 = exp(fX1) * sin(deg(fY1)) + fEcc;
local fD = 0;
if (bInside == 1) then
fD = pow(mag(fX2, fY2), 1/iSym);
else
fD = pow(mag(fX2, fY2), -1/iSym);
end
local fArg = rad(atan2(fX2, fY2)) * -1/iSym;
local fX3 = fD * cos(deg(fArg))/TWO_PI;
local fY3 = fD * sin(deg(fArg))/TWO_PI;
return mag(fX3, fY3)
end
function fn(fX, fY)
local aP = {};
local fX1 = exp(fX) * cos(deg(fY));
local fY1 = exp(fX) * sin(deg(fY)) + fEcc;
local fD = 0;
if (bInside == 1) then
fD = pow(mag(fX1, fY1), 1/iSym);
else
fD = pow(mag(fX1, fY1), -1/iSym);
end
local fArg = rad(atan2(fX1, fY1)) * -1/iSym;
for i = 0, iSym - 1 do
local fX2 = fD * cos(deg(fArg + i * TWO_PI/iSym))/TWO_PI;
local fY2 = fD * sin(deg(fArg + i * TWO_PI/iSym))/TWO_PI;
aP[i + 1] = {fX2, fY2};
end
return aP
end
function lines(aP1, aP2)
for i = 0, iSym - 1 do
local fX1 = aP1[i + 1][0 + 1];
local fY1 = aP1[i + 1][1 + 1];
local fX2 = aP2[i + 1][0 + 1];
local fY2 = aP2[i + 1][1 + 1];
--addPebble(<sPebbleType>, <tPosition>, ?, ?, ?)
--addPebble("Pebble_2", {fX1 * fScale/fNorm, 0 * fScale/fNorm, fY1 * fScale/fNorm,}, 0, 0, 0)
-----------------------
-- DO SOMETHING HERE --
-----------------------
end
end
-- calculate the distance from the origin to the center of each eye, then use it to normalize the shape to within 1 unit of the center
fNorm = norm();
for i = 0, iNy - 1 do
local fY = i * TWO_PI/iNy;
for j = iXmin * iSx, iNx * iSx - 1 do
local fX1 = j * TWO_PI/iNx/iSx;
local fX2 = (j + 1) * TWO_PI/iNx/iSx;
lines(fn(fX1, fY), fn(fX2, fY))
end
end
for i = iXmin, iNx do
local fX = i * TWO_PI/iNx;
for j = 0, iNy * iSy - 1 do
local fY1 = j * TWO_PI/iNy/iSy;
local fY2 = (j + 1) * TWO_PI/iNy/iSy;
lines(fn(fX, fY1), fn(fX, fY2))
end
end
end
flokalAdd(16, 16, 12, 5, 256, false, 20000)
This happens due to Lua 4.0 scoping rules:
Function scopes have a special limitation in that outer scopes (other than the global scope) may not be accessed. This applies to any function, but is most noticeable in the case of nested functions where you may want to access locals of the enclosing scope.
In your code fEcc
is defined in the scope of function flokalAdd
, so it can't be accessed from the inner norm
function.
You can fix this using upvalues:
Upvalues were added to work around the function scope limitation. Prefixing an outer-scope variable reference with % produces a copy of that variable as of the function's instantiation. Only the immediate scope containing the function and the global scope may be accessed in this manner.
Looking at the code, it seems that copying by value is OK. Here is the fixed version.