While such automatic updates are perfectly common in spreadsheet applications, Bash doesn’t work that way. If you want to recalculate a few values based on formulas, you have to explicitly tell Bash to do so. The example below generates the outputs that you expect and defines a function called recalculate
that you need to call after changes to the formulas or the formulas’ input variables. The rest of the trick is based around how integer evaluation works in Bash.
recalculate() {
local -n source="$1" target="$2"
target=("${source[@]}")
}
formulas=('var - 1' 'var' 'var + 1')
declare -ai arr
var=5
recalculate formulas arr
echo "${arr[@]}" # 4 5 6
var=10
recalculate formulas arr
echo "${arr[@]}" # 9 10 11
(It would be awesome if Bash had an additional pseudo-signal for the trap
command, say assignment
, which could work like trap 'echo "variable ${1} set to ${!1}"' assignment
, but AFAIK, there is no such functionality (plus no separate argument handling in trap
); hence the strikethrough. Without that kind of functionality, a function like recalculate
might be the closest you can get to the updates you asked for.)
A slightly more elaborate version of recalculate
could also (1) handle sparse arrays of formulas correctly, i.e. guarantee to store results under the same indices under which the corresponding formulas were found, and (2) introduce a “reserved” variable name, say index
, which can occur in the formulas with an obvious meaning. Just for fun, “because we can”:
recalculate() {
local -n source="$1" target="$2"
local -i index
target=()
for index in "${!source[@]}"; do
target[index]="${source[index]}"
done
}
formulas[1]='index * var - 1'
formulas[3]='index * var'
formulas[5]='index * var + 1'
declare -ai arr
var=5
recalculate formulas arr
echo "${arr[@]@A}" # declare -ai arr=([1]="4" [3]="15" [5]="26")
var=10
recalculate formulas arr
echo "${arr[@]@A}" # declare -ai arr=([1]="9" [3]="30" [5]="51")