Difference between revisions of "local"
(Create page) |
|||
(4 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
In Lua, variables can be global or local. Unlike global variables, local variables have their scope limited to the block where they are declared. | In Lua, variables can be global or local. Unlike global variables, local variables have their scope limited to the block where they are declared. | ||
− | + | == What? == | |
− | == | + | In many common programming languages, they infer the scope of your variable from where you put it in your code (ie. declaring a variable in a function means that you can only see said variable in that function), or require explicit modifiers put on declarations that specify public or private access (like in Java). By default in Lua, your variables are in the global scope, unless you define them with the <code>local</code> statement |
+ | |||
+ | A variable or function declared with the `local` statement restricts their scope to the block they're declared in. If you declare a <code>local</code> at the file level, then that value is only visible to that file, same for when you declare values within a function. | ||
+ | |||
+ | Using <code>local</code> is beneficial because: | ||
+ | * '''globals are unknown''': globals are mutable, which means you don't know what has modified it, or when. If you're aware of it, then you'd have to perform many checks whenever you wish to use it or modify it, which just adds work, not reducing it | ||
+ | * '''globals promote bad design''': Since they're so easy to access, globals generally get loaded with a bunch of stuff that is unrelated. globals generally indicate "spaghetti" code - code that seems to do everything, but none of it well, and whenever you go to edit it, it's a nightmare. | ||
+ | * '''locals are fast''': Without going into too many details, ''locals are faster in Lua''. Every global is stored in the <code>_G</code> table, and whenever you go to access one, Lua has to go hunting into this table to find it. Locals, however, are stored on 'registers', which makes them super fast to access. Adding two <code>local</code> numbers takes a single stack instruction, [https://www.lua.org/gems/sample.pdf but adding two globals might take up to four!] A program chock-full of globals could be markedly slower than one with locals. | ||
+ | |||
+ | == When should I use globals? == | ||
+ | |||
+ | All of this doesn't mean you shouldn't use Globals. In fact, if you're learning how to program, it's probably more than you have to worry about, however, if you're starting out in Lua, and you're already familiar with the idea of scopes from, say, C# or Java, then you're already halfway there. | ||
+ | |||
+ | Globals are useful in a handful of situations, however by introducing one, '''you should be strict on what you do with it'''. For example, only read from a global, don't modify any of its internal state. Don't overload your globals with functions and variables because it's "easy" - take the time to tie your program together properly (future you would love you for it). | ||
+ | |||
+ | == TL;DR == | ||
+ | In a nutshell, elect to use <code>local</code> over global declarations as it's: | ||
+ | * much safer (no other code is touching and changing the variable without your knowledge). | ||
+ | * promotes better program structure (by not cluttering up the global namespace). | ||
+ | * and above all else [http://lua-users.org/wiki/OptimisingUsingLocalVariables a very easy optimization] to make early on. | ||
+ | |||
+ | That doesn't mean you should forbid all use of globals, just when you use them, be conscious of what you're using them for. | ||
+ | |||
+ | == Example == | ||
<source lang="lua"> | <source lang="lua"> | ||
− | local | + | -- =================================================================== |
+ | -- File: "locals.lua" | ||
+ | -- =================================================================== | ||
+ | |||
+ | local LocalTest = {} | ||
+ | |||
+ | Global = "This is a global variable" | ||
+ | function GlobalFunction() | ||
+ | print("This is a global function") | ||
+ | end | ||
+ | |||
+ | local localVariable = "This is a file-scoped local variable" | ||
+ | |||
+ | local function localFunction() | ||
+ | local localFunctionVariable = "This is a function-scoped local variable" | ||
+ | local localTable = { "This is a value in a table" } | ||
+ | print("This is a local function") | ||
+ | print(Global) -- prints "This is a global variable | ||
+ | print(localVariable) -- prints "This is a file-scoped local variable" | ||
+ | print(localFunctionVariable) -- prints "This is a function-scoped local variable" | ||
+ | print(localTable[1]) -- prints "This is a value in a table" | ||
+ | end | ||
+ | |||
+ | LocalTest.exposedVariable = "This is an exposed, non-global variable" | ||
+ | |||
+ | function LocalTest.exposedFunction() | ||
+ | print("This is an exposed function from Local Test") | ||
+ | print(Global) -- prints "This is a global variable | ||
+ | print(localVariable) -- prints "This is a file-scoped local variable" | ||
+ | print(localFunctionVariable) -- prints "nil" | ||
+ | print(localTable[1]) -- throws an error | ||
+ | end | ||
+ | |||
+ | return LocalTest | ||
+ | |||
+ | -- =================================================================== | ||
+ | -- File: "main.lua" | ||
+ | -- =================================================================== | ||
+ | |||
+ | local locals = require "locals" | ||
+ | |||
+ | print(Global) -- prints "This is a global variable" | ||
+ | print(GlobalFunction()) -- prints "This is a global function" | ||
+ | |||
+ | -- Note how we have to say "look in the imported `locals` file for `exposed` variables | ||
+ | print(locals.exposedVariable) -- prints "This is an exposed, non-global variable" | ||
+ | print(exposedVariable) -- prints "nil" | ||
+ | |||
+ | -- Both of these blow up, which means the second will never get called. | ||
+ | print(locals.exposedFunction()) -- throws and error with "attempt to index global 'localTable' (a nil value)" | ||
+ | print(locals.localFunction()) -- throws an error with "attempt to call field 'localFunction' (a nil value)" | ||
+ | |||
</source> | </source> | ||
== See Also == | == See Also == | ||
[http://www.lua.org/pil/4.2.html Programming in Lua] | [http://www.lua.org/pil/4.2.html Programming in Lua] | ||
+ | |||
+ | == Other Languages == | ||
+ | {{i18n|local}} |
Latest revision as of 21:54, 17 August 2024
In Lua, variables can be global or local. Unlike global variables, local variables have their scope limited to the block where they are declared.
What?
In many common programming languages, they infer the scope of your variable from where you put it in your code (ie. declaring a variable in a function means that you can only see said variable in that function), or require explicit modifiers put on declarations that specify public or private access (like in Java). By default in Lua, your variables are in the global scope, unless you define them with the local
statement
A variable or function declared with the `local` statement restricts their scope to the block they're declared in. If you declare a local
at the file level, then that value is only visible to that file, same for when you declare values within a function.
Using local
is beneficial because:
- globals are unknown: globals are mutable, which means you don't know what has modified it, or when. If you're aware of it, then you'd have to perform many checks whenever you wish to use it or modify it, which just adds work, not reducing it
- globals promote bad design: Since they're so easy to access, globals generally get loaded with a bunch of stuff that is unrelated. globals generally indicate "spaghetti" code - code that seems to do everything, but none of it well, and whenever you go to edit it, it's a nightmare.
- locals are fast: Without going into too many details, locals are faster in Lua. Every global is stored in the
_G
table, and whenever you go to access one, Lua has to go hunting into this table to find it. Locals, however, are stored on 'registers', which makes them super fast to access. Adding twolocal
numbers takes a single stack instruction, but adding two globals might take up to four! A program chock-full of globals could be markedly slower than one with locals.
When should I use globals?
All of this doesn't mean you shouldn't use Globals. In fact, if you're learning how to program, it's probably more than you have to worry about, however, if you're starting out in Lua, and you're already familiar with the idea of scopes from, say, C# or Java, then you're already halfway there.
Globals are useful in a handful of situations, however by introducing one, you should be strict on what you do with it. For example, only read from a global, don't modify any of its internal state. Don't overload your globals with functions and variables because it's "easy" - take the time to tie your program together properly (future you would love you for it).
TL;DR
In a nutshell, elect to use local
over global declarations as it's:
- much safer (no other code is touching and changing the variable without your knowledge).
- promotes better program structure (by not cluttering up the global namespace).
- and above all else a very easy optimization to make early on.
That doesn't mean you should forbid all use of globals, just when you use them, be conscious of what you're using them for.
Example
-- ===================================================================
-- File: "locals.lua"
-- ===================================================================
local LocalTest = {}
Global = "This is a global variable"
function GlobalFunction()
print("This is a global function")
end
local localVariable = "This is a file-scoped local variable"
local function localFunction()
local localFunctionVariable = "This is a function-scoped local variable"
local localTable = { "This is a value in a table" }
print("This is a local function")
print(Global) -- prints "This is a global variable
print(localVariable) -- prints "This is a file-scoped local variable"
print(localFunctionVariable) -- prints "This is a function-scoped local variable"
print(localTable[1]) -- prints "This is a value in a table"
end
LocalTest.exposedVariable = "This is an exposed, non-global variable"
function LocalTest.exposedFunction()
print("This is an exposed function from Local Test")
print(Global) -- prints "This is a global variable
print(localVariable) -- prints "This is a file-scoped local variable"
print(localFunctionVariable) -- prints "nil"
print(localTable[1]) -- throws an error
end
return LocalTest
-- ===================================================================
-- File: "main.lua"
-- ===================================================================
local locals = require "locals"
print(Global) -- prints "This is a global variable"
print(GlobalFunction()) -- prints "This is a global function"
-- Note how we have to say "look in the imported `locals` file for `exposed` variables
print(locals.exposedVariable) -- prints "This is an exposed, non-global variable"
print(exposedVariable) -- prints "nil"
-- Both of these blow up, which means the second will never get called.
print(locals.exposedFunction()) -- throws and error with "attempt to index global 'localTable' (a nil value)"
print(locals.localFunction()) -- throws an error with "attempt to call field 'localFunction' (a nil value)"
See Also
Other Languages
Dansk –
Deutsch –
English –
Español –
Français –
Indonesia –
Italiano –
Lietuviškai –
Magyar –
Nederlands –
Polski –
Português –
Română –
Slovenský –
Suomi –
Svenska –
Türkçe –
Česky –
Ελληνικά –
Български –
Русский –
Српски –
Українська –
עברית –
ไทย –
日本語 –
正體中文 –
简体中文 –
Tiếng Việt –
한국어
More info