Is there a more consistent way to declare Bash variables and functions?
bash, shell
Solution
In order to forget about it I define the following near the top of my `.bashrc` as well as each of my Bash shell script files:
# Allow to define an alias.
#
shopt -s expand_aliases
# Defines a function given a name, empty parentheses and a block of commands enclosed in braces.
#
# @param name the name of the function.
# @param parentheses the empty parentheses. (optional)
# @param commands the block of commands enclosed in braces.
# @return 0 on success, n != 0 on failure.
#
alias def=function
# Defines a value, i.e. read-only variable, given options, a name and an assignment of the form =value.
#
# Viable options:
# * -i - defines an integer value.
# * -a - defines an array value with integers as keys.
# * -A - defines an array value with strings as keys.
#
# @param options the options. (optional)
# @param name the name of the value.
# @param assignment the equals sign followed by the value.
# @return 0 on success, n != 0 on failure.
#
alias val="declare -r"
# Defines a variable given options, a name and an assignment of the form =value.
#
# Viable options:
# * -i - defines an integer variable.
# * -a - defines an array variable with integers as keys.
# * -A - defines an array variable with strings as keys.
#
# @param options the options. (optional)
# @param name the name of the variable.
# @param assignment the equals sign followed by the value. (optional)
# @return 0 on success, n != 0 on failure.
#
alias var=declare
# Declares a function as final, i.e. read-only, given a name.
#
# @param name the name of the function.
# @return 0 on success, n != 0 on failure.
#
alias final="readonly -f"
The above definitions allow me to say for example:
- `def foo { echo bar; }`.
- `final foo`
- `var foo=bar`
- `val foo=bar`
As indicated by the comments you can mix and match various variable flags such as `var -g foo=bar` for a global (-g) variable (var) or `val -Ai foobar=([foo]=0 [bar]=1)` for a read-only (val), associative array (-A) consisting of integer (-i) values.
Implicit variable scoping too comes with this approach. Also the newly introduced keywords `def`, `val`, `var` and `final` should be familiar to any software engineer who programs in languages such as JavaScript, Java, Scala and the like.
Problem
I constantly fight with the decision of how to declare a variable or function in Bash. Given the following assumptions: - Bash is the only scripting language available. - Naming conventions are irrelevant. In the case of global variables should I use: - `foo=bar` - inside and outside of functions? - `declare -g foo=bar` - inside and outside of functions? - `local -g foo=bar` - inside of functions? In the case of local variables should I use: - `local foo=bar` - `declare foo=bar` In the case of read-only variables should I use: - `declare -r foo=bar` - `local -r foo=bar` - `readonly foo` - following [1.] or [2.] without the `-r` flag on the next line. In the case of functions should I use: - `foo() { echo bar; }` - `foo { echo bar; }` - `function foo() { echo bar; }` - `function foo { echo bar; }`