Search code examples
luascope

Lua imported global and local variables with the same name


I have a file module.lua in which I have a ( or 2? ) variable(s).

-- module.lua

test = 30
local test = 20
test = 40

print("module.lua: " .. test)

I also have my main file:

-- main.lua

require("module")
print("main.lua: " .. test)

Result of lua main.lua:

module.lua: 40
main.lua: 30

I was playing with lua variable scopes but I no longer understand What's happening here.

What happens when I have a Global variable and a local variable with the same name? (and then import that file in another one)

I guess after the local keyword, changes to the test variable are no longer global, But everything happened before it is Global. What is the use of this? why doesn't the interpreter throw an error and prevent this confusing situation? (I'm new to lua, came from the python world)

-- Trying this clearly says that changes made to test before local are global:

-- module.lua

test = 30
test = 70
local test = 20
test = 40

print("module.lua: " .. test)

lua main.lua ->

module.lua: 40
main.lua: 70

Solution

  • Global variables in recent versions of Lua are actually storing in a table called _ENV. (which is an upvalue in all contexts)

    Note: the references are ONLY considered local when it is after the complete declaration of local <var>.... This means that a statement like local test = test gets compiled to local test = _ENV.test.

    With that in mind, the files end up actually being compiled like below.

    -- module.lua
    
    _ENV.test = 30
    local test = 20
    -- after this point, any references to `test` mean the local variable
    test = 40
    
    print("module.lua: " .. test)
    
    -- main.lua
    
    require("module")
    print("main.lua: " .. _ENV.test)