Search code examples
luaworld-of-warcraft

What does it mean, in Lua, to assign an undefined identifier to an undeclared variable?


I was perusing an Lua code file, and the very top of the file contains:

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

The very first line they are doing an assignment:

TradeSkillFrameReset = TradeSkillFrame_LoadUI;

At this point in the code file they are assigning an undeclaraed identifier (TradeSkillFrame_LoadUI) to an undeclared variable (TradeSkillFrameReset). Is this allowed in Lua?

  • is variable declaration implicit?
  • are all undeclared identifiers assumed to be forward declarations?

The more confusing thing is that the first TradeSkillFrame_LoadUI seems to do is call itself:

TradeSkillFrame_LoadUI = function()
   TradeSkillFrameReset();

How is this not an infinite loop?


Edit: Added remaining references to TradeSkillFrameReset and TradeSkillFrame_LoadUI.


Solution

  • If TradeSkillFrame_LoadUI is a global function, the first statement captures this function in TradeSkillFrameReset.

    The assigment to TradeSkillFrame_LoadUI then replaces the global function with a new one, that at first calls the original function through the TradeSkillFrameReset reference.

    This pattern is called "function hooking", here is some more information about the general technique and some World of Warcraft Lua environment specific details (where this script may come from, according to the function's name)

    Some example code, to make this clear:

    function SomeGlobalFunction()
        print("I'm the original global function")
    end
    
    OrigFunction = SomeGlobalFunction
    
    SomeGlobalFunction = function()
        OrigFunction()
        print("And here's the modfied one...")
    end
    
    --...
    SomeGlobalFunction()
    

    this will print the following output:

    I'm the original global function

    And here's the modfied one...

    As a side note, Lua's name is not all capitalized.