¿Qué significa, en Lua, para asignar un identificador definido a una variable no declarada?

StackOverflow https://stackoverflow.com/questions/3949534

  •  08-10-2019
  •  | 
  •  

Pregunta

Yo estaba hojeando un archivo de código Lua, y la parte superior del archivo contiene:

    1  | TradeSkillFrameReset = TradeSkillFrame_LoadUI;
    2  | 
    3  | TradeSkillFrame_LoadUI = function()
    4  |    TradeSkillFrameReset();
            ...
    112|    TradeSkillFrame_LoadUI = TradeSkillFrameReset;
            ...
    114| end;

La primera línea que están haciendo un trabajo:

TradeSkillFrameReset = TradeSkillFrame_LoadUI;

En este punto en el archivo de código que están asignando un identificador undeclaraed (TradeSkillFrame_LoadUI) a una variable no declarada (TradeSkillFrameReset). Esto está permitido en Lua?

  • es la declaración de variables implícita?
  • son todos los identificadores declarados supone que son declaraciones adelantadas?

Lo más confuso es que la primera TradeSkillFrame_LoadUI parece que hacer es llamar a sí mismo:

TradeSkillFrame_LoadUI = function()
   TradeSkillFrameReset();

¿Cómo es esto no es un bucle infinito?


Editar:. añadido referencias a las TradeSkillFrameReset y TradeSkillFrame_LoadUI restante

¿Fue útil?

Solución

Si TradeSkillFrame_LoadUI es una función global, las primeras capturas de los estados esta función en TradeSkillFrameReset.

El assigment a TradeSkillFrame_LoadUI entonces reemplaza la función global con una nueva, que al principio llama a la función original a través de la referencia TradeSkillFrameReset.

Este patrón se llama "función de enganche", aquí hay más información sobre la técnica general y algunos World of Warcraft Lua detalles específicos ambiente (donde este script puede provenir de, de acuerdo con el nombre de la función)

Algunos código de ejemplo, para aclarar esto:

function SomeGlobalFunction()
    print("I'm the original global function")
end

OrigFunction = SomeGlobalFunction

SomeGlobalFunction = function()
    OrigFunction()
    print("And here's the modfied one...")
end

--...
SomeGlobalFunction()

Esto imprimirá el siguiente resultado:

Soy función global originales

Y aquí está el modfied ...

Como nota al margen, el nombre de Lua es no todos capitalizado .

Otros consejos

En la primera línea, ya que TradeSkillFrame_LoadUI es una variable no inicializada, a continuación, esta primera línea:

TradeSkillFrameReset = TradeSkillFrame_LoadUI;

¿Es lo mismo que hacer:

TradeSkillFrameReset = nil

La función por debajo de ese no entra en un bucle infinito, porque en realidad no es TradeSkillFrameReset 'que apunta a nada' allí.

Mi conjetura es que más adelante en el código, que se ha inicializado correctamente. De esta manera:

TradeSkillFrameReset = TradeSkillFrame_LoadUI;

TradeSkillFrame_LoadUI = function()  -- 1. function declaration
   TradeSkillFrameReset();

   [...snip...]
end;

[... snip ...]
TradeSkillFrameReset = somethingElse -- 2. initialized to something else
TradeSkillFrame_LoadUI()             -- 3. function invocation

El truco es que se puede definir una función de 1, y utilizar el valor de una variable, el 3, mientras que el cambio en 2.

Avísame si esto no es lo suficientemente clara.

A menos que el comportamiento de las variables globales se ha modificado en el medio que está utilizando se ha modificado, la declaración no hace absolutamente nada.

local TradeSkillFrameReset = TradeSkillFrame_LoadUI

tendría un efecto, la creación de una variable local "ranura" y hacer el código más allá que el uso de punto de la caja de la variable local para TradeSkillFrameReset en lugar de hacer una búsqueda de variable global para ello. Sin embargo, como lo es en el código que envió, simplemente se asigna a la variable global a cero, lo cual tiene el efecto de borrar que, en otras palabras, no tiene efecto si ya fue nula.

Las razones que podría estar allí:

1) El entorno se ejecuta el código en sí algo especial cuando una asignación variable global se hace, más que el comportamiento predeterminado de una asignación simple. No creo que esto es probable, sin embargo, como si no hubiera ningún comportamiento especial las operaciones de búsqueda de la TradeSkillFrame_LoadUI nula probablemente causaría un error.

2) La razón más probable es simplemente para facilitar la lectura. Es para hacerle saber que TradeSkillFrameReset pueden asignar adecuadamente a algún lugar más tarde enterrado en el código en el que no se dará cuenta de que tan fácilmente.

Lo más importante para llevar es que es fácil para el código Lua para inyectar variables globales en otro código Lua. He utilizado una gran cantidad de Lua donde utilizan el medio ambiente para agregar VARs globales. El hecho de que una var no está definida en ese archivo con toda seguridad no significa que no existe. Ni siquiera tiene que ser definido como una variable global en otro archivo, porque se puede inyectar en el entorno de programación de mesa como si se tratara de cualquier otra tabla.

Me imagino su hacer algo similar a la función de elevación de Javascript, que se puede leer aquí: Hacer referencia a un valor de JavaScript antes de que se declara - ¿puede alguien explicar este

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top