Che cosa significa, in Lua, per assegnare un identificatore non definito a una variabile non dichiarata?

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

  •  08-10-2019
  •  | 
  •  

Domanda

Stavo sfogliando un file di codice Lua, e parte superiore del file contiene:

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

La prima linea che stanno facendo un incarico:

TradeSkillFrameReset = TradeSkillFrame_LoadUI;

A questo punto nel file di codice sono l'assegnazione di un identificatore undeclaraed (TradeSkillFrame_LoadUI) per una variabile non dichiarata (TradeSkillFrameReset). E 'questo permesso in Lua?

  • è la dichiarazione variabile implicita?
  • sono tutti gli identificatori non dichiarate assunti come dichiarazioni previsionali?

La cosa più confusa è che il primo TradeSkillFrame_LoadUI sembra fare è chiamare se stesso:

TradeSkillFrame_LoadUI = function()
   TradeSkillFrameReset();

Come non è questo un ciclo infinito?


Modifica:. Aggiunto riferimenti a TradeSkillFrameReset e TradeSkillFrame_LoadUI restante

È stato utile?

Soluzione

Se TradeSkillFrame_LoadUI è una funzione globale, le prime catture dichiarazione questa funzione in TradeSkillFrameReset.

L'assigment di TradeSkillFrame_LoadUI sostituisce quindi la funzione globale con uno nuovo, che all'inizio chiamate la funzione originale attraverso il riferimento TradeSkillFrameReset.

Questo modello si chiama "la funzione di aggancio", qui è qualche informazione in più sulla tecnica generale e un po ' World of Warcraft Lua dettagli specifici ambiente (in cui questo script può venire da, in base al nome della funzione)

Alcuni codice di esempio, per rendere questo chiaro:

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

OrigFunction = SomeGlobalFunction

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

--...
SomeGlobalFunction()

questo stampa il seguente output:

  

Sono la funzione globale originale

     

Ed ecco quello modfied ...

Come nota a margine, il nome di Lua è non tutte capitalizzate .

Altri suggerimenti

Nella prima riga, poiché TradeSkillFrame_LoadUI è una variabile non inizializzata, allora questa prima riga:

TradeSkillFrameReset = TradeSkillFrame_LoadUI;

E 'lo stesso di fare:

TradeSkillFrameReset = nil

La funzione qui sotto che non entra in un ciclo infinito perché TradeSkillFrameReset non è in realtà 'che punta a qualcosa di' là.

La mia ipotesi è che in seguito nel codice, si ottiene correttamente inizializzata. In questo modo:

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

Il trucco è che si può definire una funzione il 1 °, e utilizzare il valore di una variabile su 3, mentre si cambia su 2.

Fammi sapere se questo non è abbastanza chiaro.

A meno che il comportamento delle variabili globali è stato modificato in un ambiente che si sta utilizzando è stato modificato, la dichiarazione non fa assolutamente nulla.

local TradeSkillFrameReset = TradeSkillFrame_LoadUI

avrebbe un effetto, la creazione di una variabile locale "slot" e rendere il codice passato che l'uso punto lo slot variabile locale per TradeSkillFrameReset piuttosto che fare una ricerca variabile globale per esso. Tuttavia, come è nel codice che hai postato, assegna semplicemente la variabile globale a zero, che ha l'effetto di cancellare esso, in altre parole, nessun effetto se era già pari a zero.

Le ragioni potrebbe essere lì:

1) L'ambiente il codice è in esecuzione in fa qualcosa di speciale quando l'assegnazione variabile globale è fatto, piuttosto che il comportamento predefinito di un semplice incarico. Non credo che questo è probabile, però, come se ci fosse un comportamento speciale la ricerca del TradeSkillFrame_LoadUI nil causerebbe probabilmente un errore.

2) Il più probabile ragione è semplicemente per migliorare la leggibilità. E 'per farvi sapere che TradeSkillFrameReset essere assegnato correttamente per qualche parte in seguito sepolto nel codice in cui non si dovrebbe notare come facilmente.

La cosa principale da togliere è che è facile per il codice Lua per iniettare le variabili globali in altro codice Lua. Ho usato un sacco di Lua dove usano l'ambiente per aggiungere vars globali. Solo perché un var non è definita nel file quasi sicuramente non significa che non esista. Non ha nemmeno bisogno di essere definita come una variabile globale in un altro file, perché si può iniettare nella tabella nell'ambiente di programmazione, come se si trattasse di qualsiasi altra tabella.

Direi proprio qualcosa di simile alla funzione facendo sollevamento di Javascript, che potete leggere qui: Riferimento a un valore JavaScript prima che venga dichiarata - qualcuno può spiegare questo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top