This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Last revision Both sides next revision
commands:builtin:local [2012/01/01 19:29]
ormaaj created, sleepy, write it later. :)
commands:builtin:local [2012/02/01 09:02]
ormaaj Turns out a lot of this is wrong. Sorry. :(
Line 7: Line 7:
 <WRAP center round todo 60%> <WRAP center round todo 60%>
-TODO: Describe Bash scope rules in some detail. Point pages like [[commands:​builtin:​declare]] and those dealing with functions here for more details on locals and dynamic scope. ​+TODO: Describe Bash scope rules in some detail. Point pages like [[commands:​builtin:​declare]] and those dealing with functions here for more details on locals and dynamic scope. ​This wiki could use a dedicated article about functions. Not sure how to organize all this information yet. Help if you can. ^_^
 </​WRAP>​ </​WRAP>​
 +Warning - mountains of fail below on my part. Even I don't understand this after all. Going back to do more testing.
 +<WRAP hide>
 +The most important thing to know about variable scope in Bash is that the variables visible from within the body of a function are always the same as those which are visible //at the time a function is called//. Two equivalent ways of stating how this works:
 +  * A called function sees a cascading view of all variables out to the first caller which declared a local by a given name. Variable scope works much like subclass polymorphism in this way, or CSS inheritance.
 +Or alternatively:​
 +  * All descendant callees of a function see locals defined in the scope of the caller until another function defines a local of the same name, whose callees and all further descendents will then see the new variable.
 +This differs from the majority of other languages except those with so-called [[http://​​dynamic-scope|dynamic scope]], though shell functions are so vastly unconventional in other ways that it's difficult to judge whether this behavior is good or bad by contrast to the conventions of other languages. If a function doesn'​t take care to locally define the variables used by commands then the value of any given variable can differ depending on the context from which it is called. Alternatively,​ almost all gotchas regarding use of global variables in most languages also apply at least equally to Bash, if not moreso, as Bash lacks namespaces and a powerful type system. ​
 +This discussion inevitably brings up questions about closures, first-class-functions,​ higher-order-functions,​ continuations,​ function-objects,​ and the like. The answer is that these concepts are rarely applicable to Bash for the aforementioned reason that "​functions"​ are just distantly reminiscent of what one would typically call a "​conventional"​ function. Function definitions can't be nested [[howto/​collapsing_functions|in the usual sense]], nor can they be passed around to, or returned from functions either as objects or by reference.
 ===== Examples ===== ===== Examples =====
 +Notice that nesting function definitions doesn'​t impact the results.
 +$ ( f() { local x=2; g() { echo "​$x";​ }; }; f; g )
 +$ ( f() { local x=2; g() { echo "​$x";​ }; g; }; f )
 +$ ( g() { echo "​$x";​ }; f() { local x=2; g; }; f )
 +"​inheritance-like"​ behavior. Notice "​f"​ doesn'​t care that a global "​x"​ is in the scope of the definition. Only "​call-time"​ matters.
 +f() ((
 +    x++
 +g() {
 +    local x
 +    f
 +    echo "​$x"​
 +g         # prints 1
 +echo "​$x"​ # prints 0
 ===== Portability considerations ===== ===== Portability considerations =====
 +  * ''​local''​ is not specified by POSIX. Additionally,​ ''​local''​ is Bash-only. It is identical to [[declare]] in every way, and takes all the same options, except that usage outside of a function is an error. Using ''​declare''​ within a function has the same effect as local unless the -g option is given. ''​typeset''​ is technically more portable than both ''​local''​ and ''​declare'',​ but labeled as "​depreciated"​ in the Bash manpage.
 +  * POSIX does not specify function local variables and their behavior is therefore not formally defined and often largely undocumented. The Korn shell and derivatives including Bash and Zsh thankfully mostly agree on semantics (when using the "​POSIX-style"​ function definition syntax), and overload the typeset builtin (or declare and local) to declare variables as local.
 ===== See also ===== ===== See also =====
 +  * http://​​scripting/​basics#​variable_scope
  • commands/builtin/local.txt
  • Last modified: 2012/04/23 01:30
  • by ormaaj