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; }`

Original source