Comparison between local and global variables:
- Implementation: Locals index an array of registers on the stack, with hard-coded integer index (at least in the standard implementation -- LuaImplementations). Globals index from a table (or userdata), typically with variable name string, stored as constant or variable, as the key.
- Note: In 5.2.0work3, the concept of globals remains in the language but is eliminated from the VM (no special GETGLOBAL/SETGLOBAL opcodes). From the VM perspective, globals are no different than gets/sets from a local (actually lexical upvalue) table.
- Note: A local promoted to an upvalue is treated slightly differently in the VM from regular locals. Upvalues are accessed via special VM opcodes.
- Performance: The above point implies that locals can be a bit faster (OptimisingUsingLocalVariables). Still, table indexing is a fairly efficient operation in Lua (e.g. strings are interned with precomputed hash), so this point can often be ignored unless profiling indicates optimization is needed.
- Syntax: If an environment table is set, globals can be accessed in Lua code with or without explicitly naming the environment table they come from:
foo
, _G.foo
, or getfenv().foo
(or in 5.2.0work3, _ENV.foo
). This allows different styles of environment usage, such as in ModuleDefinition.
- Scope: Locals are scoped within a lexical block. Globals are scoped within any number of functions assigned a given environment table at run-time. In 5.2.0work3, globals are scoped within any number of lexical blocks assigned a given environment table (declared at compile-time but assigned at run-time).
- Declaration: Locals must be explicitly declared, with
local
statement, to use them. Assignments are global-by-default not LocalByDefault. Globals can be accessed on-the-fly, even with variable name set at runtime (e.g. "foo=io.stdin:read'*l'; return _G[foo]
"). The list of locals is defined statically. The list of globals may be determined at run-time and can even change during program execution.
- Program Analysis: The above point implies uses of local variables can often be more easily traced to their definition and vice-versa. This implies that locals can be easier to use for static program analysis, such as correctness checking/DetectingUndefinedVariables/LuaInspect and optimization (e.g. SourceOptimizer and LuaImplementations). Locals also reduce unintended coupling.
- Standard library access: The standard library is normally exposed to a chunk via globals. An alternative though is to explicitly pass _G or its elements as local parameters, "
local _G, math, math_sqrt = ...
", but this can be exhaustive.
- Precedence: Locals override globals. This remains true even if the globals have a more specific scope, so in 5.2.0work3, "
local x = 1; do local _ENV = {x=2}; return x end
" returns 1.
- Side-effects on access: Sets/gets to globals can trigger side-effects or custom actions via metamethods on the environment table. This is sometimes how two different environment tables are merged (e.g. package.seeall) or special effects like strict.lua (runtime DetectingUndefinedVariables) or SymbolicDifferentiation may be implemented.
- Scope passing: A complete set of globals or references to globals can be passed to different scopes by passing the environment table. Global scope is in a way a "first-class valve" in Lua. Locals can not be passed around as such except by creating a closure with the locals explicitly referenced. One exception is debug.getlocal/setlocal as used in StringInterpolation, but this is a hack.
- Bytecode introspection: Globals are more visible in the bytecode. Global get/sets become GETGLOBAL/SETGLOBAL opcodes with the given variable name. In 5.2.0work3, these become GETTABUP/SETTABUP opcodes [1]. It is possible to list all the globals read or written byte a compiled chunk, as used by DetectingUndefinedVariables.
- Limit on number: There is a limit to the number of locals per function (MAXLOCALS, typically 200).
RecentChanges · preferences
edit · history
Last edited July 10, 2010 9:35 pm GMT (diff)