2011-05-20 10 views

Respuesta

29

Lua es un lenguaje dinámico y las funciones son solo un tipo de valor que se puede llamar con el operador (). Entonces, realmente no necesita reenviar declarar la función tanto como asegurarse de que la variable en el alcance cuando la llama es la variable que cree que es.

Esto no es un problema en absoluto para las variables globales que contienen funciones, ya que el entorno global es el lugar predeterminado para buscar resolver un nombre de variable. Sin embargo, para las funciones locales, debe asegurarse de que la variable local ya está en el alcance en el punto léxico donde necesita llamar al valor que almacena, y también asegurarse de que en tiempo de ejecución realmente contenga un valor que se pueda llamar .

Por ejemplo, aquí es un par de funciones locales mutuamente recursivos:

local a,b 
a = function() return b() end 
b = function() return a() end 

Por supuesto, es también un ejemplo de la utilización de cola de llamadas para permitir la repetición infinita que no hace nada, pero el punto aquí es el declaraciones Al declarar las variables con local antes de que cualquiera tenga una función almacenada en él, se sabe que esos nombres son variables locales en el alcance léxico del resto del ejemplo. Entonces las dos funciones se almacenan, cada una refiriéndose a la otra variable.

+1

Bien, gracias. Pude resolverlo por mi cuenta, pero esta respuesta fue útil, no obstante. –

9

Puede reenviar declarar una función declarando su nombre antes de declarar el cuerpo de la función real:

local func1 
local func2 = function() 
    func1() 
end 
func1 = function() 
    --do something 
end 

Sin embargo hacia adelante declaraciones sólo son necesarios cuando se declara funciones de ámbito local. Que generalmente es lo que quiere hacer, pero Lua también es compatible con una sintaxis más como C, en cuyo caso la declaración hacia adelante no es necesario:

function func2() 
    func1() 
end 
function func1() 
    --do something 
end 
+4

En realidad, su primer ejemplo no hace lo que usted cree que ocurre ya que el segundo 'local func1' declara una * nueva * variable de ese nombre y deja el primer' func1' huérfano y todavía se establece en 'nil'. – RBerteig

+0

Vaya, buen punto, arreglaré eso – jhocking

+1

Su segundo ejemplo también es malo, porque ingenuamente llamar a "func2" desde abajo func1 funcionaría, pero no a causa de ningún tipo de "declaración directa". Por el contrario, func1 se declara en el entorno global (_G), y cuando func2 busca func1, comprueba _G. Eso significa que func1 se declara antes de ejecutar func2 y, por lo tanto, cuando se comprueba _G, funciona. Lanzar una llamada func2 inmediatamente después de definir func2 da como resultado un error ... porque func1 no está declarado/definido. – LuaWeaver

0

Pruebas bajo la lua incrustado en Freeswitch, declaración adelantada no funciona:

fmsg("CRIT", "It worked.") 
function fmsg(infotype, msg) 
    freeswitch.consoleLog(infotype, msg .. "\n") 
end 

resultado:

[ERR] mod_lua.cpp: 203 /usr/local/freeswitch/scripts/foo.lua:1: intento de llamar 'FMSG' global (un valor nulo)

Invertir el orden funciona (duh).

0

No funciona si intento llamar a la función antes de la definición. Estoy usando este script de Lua en nginx conf.

lua entry thread aborted: runtime error: lua_redirect.lua:109: attempt to call global 'throwErrorIfAny' (a nil value)

Código de fragmentos -

... 
throwErrorIfAny() 
... 

function throwErrorIfAny() 
    ngx.say("request not allowed") 
    ngx.exit(ngx.HTTP_OK) 
end 

Teniendo en cuenta algunas otras respuestas también han señalado que no funcionó para ellos tampoco, es posible que la declaración de avance de Lua no funciona con otras herramientas .

PD: Funciona bien si antes pongo la definición de función y luego la llamo después.

Cuestiones relacionadas