A local that wasn't a new variable
- #bug-fix
- #variables
- #arithmetic
- #bash-compat
local is supposed to give a function its own variable. In huck it gave you the
outer one with a fresh value written into it — and everything else about that
variable came along.
The clearest way this bit you was declare -i. Mark a global as an integer, then
shadow it in a function:
# before
$ huck -c 'declare -i count=5; tally(){ local count=abc; echo "$count"; }; tally'
0# after
$ huck -c 'declare -i count=5; tally(){ local count=abc; echo "$count"; }; tally'
abcThe local inherited the integer attribute, so abc was evaluated as arithmetic
and became 0. Not a cosmetic difference — a wrong value, silently.
Arrays were worse, because the outer contents survived too:
# before
$ huck -c 'declare -a paths=(/usr /bin); f(){ local paths=x; echo "${paths[@]}"; }; f'
x /bin# after
$ huck -c 'declare -a paths=(/usr /bin); f(){ local paths=x; echo "${paths[@]}"; }; f'
xdeclare inside a function had the same root, and there it also failed to hide
the outer value at all:
# before
$ huck -c 'limit=10; check(){ declare limit; echo "[${limit-unset}]"; }; check'
[10]# after
$ huck -c 'limit=10; check(){ declare limit; echo "[${limit-unset}]"; }; check'
[unset]Only one attribute genuinely crosses into a local, and that is export — which
also means local +x now does something, instead of being a documented no-op.
Arithmetic that answered when it should have refused
Two more from the same pass. A quoted operand inside $(( )) is a syntax error
in bash; huck stripped the quotes and computed a number:
# before
$ huck -c "echo \$(( '5' + 1 ))"
6# after
$ huck -c "echo \$(( '5' + 1 ))"
huck: line 1: '5' + 1 : syntax error: operand expected (error token is "'5' + 1 ")$(( 'x' )) was the alarming case: a quoted string was silently reading the
variable x.
And when arithmetic did fail, huck described it in its own words with an empty error token. It now says what bash says, including the dedicated message for an unfinished subscript:
# before
$ huck -c 'echo $((x[))'
huck: line 1: x[: syntax error: operand expected (error token is "[")# after
$ huck -c 'echo $((x[))'
huck: line 1: x[: bad array subscript (error token is "x[")Still open
Fixing these turned up seven neighbours, filed rather than folded in. Three are one coherent piece of work — the rules for converting a variable between a scalar, an indexed array and an associative one, which four declaration builtins each implement separately and get wrong in both directions (#347, #697, #698).
The rest: a quoted array subscript still evaluates where bash refuses (#699), reading a script from a pipe joins a trailing backslash to the next line before the parser sees it, where running the same file does not (#701), and two small arithmetic-diagnostic corners (#703, #704).