Oscar Gomez
Oscar Gomez

Reputation: 18488

lua variables scope

I am aware there are other similar topics but could not find an straight answer for my question.

Suppose you have a function such as:

function aFunction()
  local aLuaTable = {}
  if (something) then
     aLuaTable = {}
  end
end

For the aLuaTable variable inside the if statement, it is still local right?. Basically what I am asking is if I define a variable as local for the first time and then I use it again and again any number of times will it remain local for the rest of the program's life, how does this work exactly?.

Additionally I read this definition for Lua global variables:

Any variable not in a defined block is said to be in the global scope. Anything in the global scope is accessible by all inner scopes.

What is it meant by not in a defined block?, my understanding is that if I "declare" a variable anywhere it will always be global is that not correct?.

Sorry if the questions are too simple, but coming from Java and objective-c, lua is very odd to me.

Upvotes: 7

Views: 14719

Answers (2)

Nicol Bolas
Nicol Bolas

Reputation: 473242

For the aLuaTable variable inside the if statement, it is still local right?

I don't understand how you're confused here; the rule is the exact same as it is for Java. The variable is still within scope, so therefore it continues to exist.

A local variable is the equivalent of defining a "stack" variable in Java. The variable exists within the block scope that defined it, and ceases to exist when that block ends.

Consider this Java code:

public static void main()
{
  if(...)
  {
    int aVar = 5; //aVar exists.
    if(...)
    {
      aVar = 10; //aVar continues to exist.
    }
  }

  aVar = 20; //compile error: aVar stopped existing at the }
}

A "global" is simply any variable name that is not local. Consider the equivalent Lua code to the above:

function MyFuncName()
  if(...) then
    local aVar = 5 --aVar exists and is a local variable.

    if(...) then
      aVar = 10 --Since the most recent declaration of the symbol `aVar` in scope
                --is a `local`, this use of `aVar` refers to the `local` defined above.
    end
  end

  aVar = 20 --The previous `local aVar` is *not in scope*. That scope ended with
            --the above `end`. Therefore, this `aVar` refers to the *global* aVar.
end

What in Java would be a compile error is perfectly valid Lua code, though it's probably not what you intended.

Upvotes: 5

Mud
Mud

Reputation: 28991

"Any variable not in a defined block is said to be in the global scope."

This is simply wrong, so your confusion is understandable. Looks like you got that from the user wiki. I just updated the page with the correction information:

Any variable that's not defined as local is global.

my understanding is that if I "declare" a variable anywhere it will always be global

If you don't define it as local, it will be global. However, if you then create a local with the same name, it will take precedence over the global (i.e. Lua "sees" locals first when trying to resolve a variable name). See the example at the bottom of this post.

If I define a variable as local for the first time and then I use it again and again any number of times will it remain local for the rest of the program's life, how does this work exactly?

When your code is compiled, Lua tracks any local variables you define and knows which are available in a given scope. Whenever you read/write a variable, if there is a local in scope with that name, it's used. If there isn't, the read/write is translated (at compile time) into a table read/write (via the table _ENV).

local x = 10 -- stored in a VM register (a C array)
y = 20       -- translated to _ENV["y"] = 20

x = 20       -- writes to the VM register associated with x
y = 30       -- translated to _ENV["y"] = 30

print(x)     -- reads from the VM register
print(y)     -- translated to print(_ENV["y"])

Locals are lexically scoped. Everything else goes in _ENV.

x = 999

do -- create a new scope
    local x = 2
    print(x)      -- uses the local x, so we print 2
    x = 3         -- writing to the same local
    print(_ENV.x) -- explicitly reference the global x our local x is hiding
end

print(x) -- 999

Upvotes: 16

Related Questions