Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
commands:builtin:declare [2011/01/04 06:56]
thebonsai [Errors]
commands:builtin:declare [2013/04/14 22:11] (current)
ormaaj mirabilos' example for eventual portability section
Line 28: Line 28:
 |''​[-+]a'' ​ |make NAMEs indexed arrays (removing with ''​+a''​ is valid syntax, but leads to an error message) ​ | |''​[-+]a'' ​ |make NAMEs indexed arrays (removing with ''​+a''​ is valid syntax, but leads to an error message) ​ |
 |''​[-+]A'' ​ |make NAMEs associative arrays ​ | |''​[-+]A'' ​ |make NAMEs associative arrays ​ |
 +|''​[-+]c'' ​ | **Undocumented** convert NAMEs to "​capcase"​ on assignment (makes the first letter upper-case and the rest lower). Requires Bash built with ''​-DCASEMOD_CAPCASE'' ​ |
 |''​-f'' ​ |restrict action or display to function names and definitions (removing with ''​+f''​ is valid syntax, but leads to an error message) ​ | |''​-f'' ​ |restrict action or display to function names and definitions (removing with ''​+f''​ is valid syntax, but leads to an error message) ​ |
 |''​-F'' ​ |restrict display to function names only (plus line number and source file when debugging) ​ | |''​-F'' ​ |restrict display to function names only (plus line number and source file when debugging) ​ |
Line 33: Line 34:
 |''​[-+]i'' ​ |make NAMEs have the "​integer"​ attribute ​ | |''​[-+]i'' ​ |make NAMEs have the "​integer"​ attribute ​ |
 |''​[-+]l'' ​ |convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters) ​ | |''​[-+]l'' ​ |convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters) ​ |
 +|''​[-+]n'' ​ |make NAME a reference to the variable named by its value. Introduced in Bash 4.3-alpha ​ |
 |''​-p'' ​ |display the attributes and value of each NAME  | |''​-p'' ​ |display the attributes and value of each NAME  |
 |''​[-+]r'' ​ |make NAMEs readonly (removing with ''​+r''​ is valid syntax, but not possible) ​ | |''​[-+]r'' ​ |make NAMEs readonly (removing with ''​+r''​ is valid syntax, but not possible) ​ |
Line 51: Line 53:
 |!= 0  |attempt to use ''​+a''​ to "​destroy"​ an array  | |!= 0  |attempt to use ''​+a''​ to "​destroy"​ an array  |
 |!= 0  |attemt to display a non-existent function with ''​-f'' ​ | |!= 0  |attemt to display a non-existent function with ''​-f'' ​ |
 +
 +===== Notes =====
 +
 +Unix shells offer very few datatypes. Bash and some other shells extend this by allowing "​attributes"​ to be set on variable names. The only attributes specified by POSIX are ''​export''​ and ''​readonly'',​ which are set by their own dedicated builtins. Datatypes in bash have a few other interesting capabilities such as the ability to modify data on assignment.
  
 ===== Examples ===== ===== Examples =====
Line 75: Line 81:
 } }
 </​code>​ </​code>​
 +
 +==== Nameref ====
 +
 +Bash 4.3 adds a new way to indirectly reference variables. ''​typeset -n''​ can be used to make a variable indirectly refer to another. In Bash, the lvalue of the assignment given to ''​typeset -n''​ will refer to the variable whose name is expanded on the RHS.
 +
 +<​code>​
 +# Sum a set of arrays and assign the result indirectly, also printing each intermediary result (without portability workarounds)
 +# sum name arrname [ arrname ... ]
 +function sum {
 +    typeset -n _result=$1 _arr
 +    typeset IFS=+
 +    _result=0
 +    for _arr in "​${@:​2}";​ do                        # Demonstrate the special property of "​for"​ on a nameref.
 +        (( _result += ${_arr[*]} ))
 +        printf '%s = %d\n' "​${!_result}"​ "​$_result"​ # Demonstrate the special property of ${!ref} on a nameref.
 +    done
 +}
 +
 +a=(1 2 3) b=(6 5 4) c=(2 4 6)
 +sum total a b c
 +printf 'Final value of "​total"​ is: %d\n' "​$total"​
 +</​code>​
 +<div hide>
 +function sum {
 + typeset -n _result=$1
 + shift
 + typeset IFS=+ _arrx
 + _result=0
 + for _arrx in "​$@";​ do                        # Demonstrate the special property of "​for"​ on a nameref.
 + typeset -n _arr=$_arrx
 + (( _result += ${_arr[*]} ))
 + printf '%s = %d\n' "​${!_result}"​ "​$_result"​ # Demonstrate the special property of ${!ref} on a nameref.
 + done
 +}
 +
 +a=(1 2 3); b=(6 5 4); c=(2 4 6)
 +sum total a b c
 +printf 'Final value of "​total"​ is: %d\n' "​$total"​
 +</​div>​
 +
 +''​typeset -n''​ is currently implemented in ksh93, mksh, and Bash 4.3. Bash and mksh's implementations are quite similar, but much different from ksh93'​s. See [[#​portability_considerations | Portability considerations]] for details. ksh93 namerefs are much more powerful than Bash'​s.
  
 ===== Portability considerations ===== ===== Portability considerations =====
  
   * ''​declare''​ is not specified by POSIX(r)   * ''​declare''​ is not specified by POSIX(r)
-  * there is Bash synonym ''​typeset''​, which is marked ​as obsolete: Use ''​declare'' ​for Bash, other shells ​may use ''​typeset''​ +  * ''​declare'' ​is unique to Bash and totally non-portable with the possible exception of Zsh in Bash compatibility mode. Bash marks the synonym ''​typeset''​ as obsolete, which in Bash behaves identically to ''​declare''​. All other Korn-like ​shells use ''​typeset''​, so it probably isn't going away any time soon. Unfortunately,​ being a non-standard builtin, ​''​typeset'' ​differs significantly between shells. ksh93 also considers ''​typeset''​ a special ​builtin, while Bash does not - even in POSIX mode. If you use ''​typeset''​you should attempt to only use it in portable ways. 
-  * the Korn shell ''​typeset''​ special ​command is not fully compatiblebut some options are+  * **todo** nameref portability...
  
 ===== See also ===== ===== See also =====
Line 86: Line 133:
   * [[commands:​builtin:​readonly]]   * [[commands:​builtin:​readonly]]
   * [[commands:​builtin:​unset]]   * [[commands:​builtin:​unset]]
 +  * [[http://​austingroupbugs.net/​view.php?​id=351 | declaration commands]] will change the behavior of certain builtins such as ''​export''​ in the next version of POSIX.