Problem
When using local -n (nameref) to reference an indexed array, the +=("value") append operator silently does nothing. The caller's array remains empty.
Scalar assignment through nameref works. Associative array key assignment through nameref works. Only indexed array append via += is broken.
Reproduction
append_via_ref() {
local -n ref="$1"
ref+=("x")
ref+=("y")
}
target=()
append_via_ref target
echo "${#target[@]}" # Expected: 2, Actual: 0
echo "${target[*]}" # Expected: x y, Actual: (empty)
Impact
wedow/harness uses this exact pattern to collect plugin ordering:
# bin/harness — _collect_hooks_from()
_collect_hooks_from() {
local dir="$1"
local -n map_ref="$2" # → associative array (works)
local -n order_ref="$3" # → indexed array (BROKEN)
for f in "${dir}"/*; do
[[ -x "${f}" ]] || continue
local base="$(basename "${f}")"
map_ref["${base}"]="${f}" # ✓ works
order_ref+=("${base}") # ✗ broken — append lost
done
}
What works vs what doesn't
# ✓ Direct array append
arr=()
arr+=("a")
echo "${#arr[@]}" # → 1
# ✓ Nameref scalar assignment
set_val() { local -n r="$1"; r="hello"; }
x=""; set_val x; echo "${x}" # → hello
# ✓ Nameref assoc array key assignment
set_key() { local -n r="$1"; r["k"]="v"; }
declare -A m; set_key m; echo "${m[k]}" # → v
# ✗ Nameref indexed array append
append() { local -n r="$1"; r+=("item"); }
a=(); append a; echo "${#a[@]}" # → 0 (expected 1)
Test cases
# Basic append through nameref
pusher() {
local -n ref="$1"
ref+=("alpha")
ref+=("beta")
ref+=("gamma")
}
items=()
pusher items
echo "${#items[@]}"
# Expected: 3
echo "${items[0]} ${items[1]} ${items[2]}"
# Expected: alpha beta gamma
# Append to non-empty array
starter=(existing)
pusher starter
echo "${#starter[@]}"
# Expected: 4
echo "${starter[0]}"
# Expected: existing
# Index assignment through nameref (should also work)
set_index() {
local -n ref="$1"
ref[0]="first"
ref[1]="second"
}
arr2=()
set_index arr2
echo "${arr2[0]} ${arr2[1]}"
# Expected: first second
# Multiple namerefs — one assoc, one indexed (harness pattern)
collect() {
local -n map_ref="$1"
local -n order_ref="$2"
map_ref["a"]="/path/a"
order_ref+=("a")
map_ref["b"]="/path/b"
order_ref+=("b")
}
declare -A mymap
myorder=()
collect mymap myorder
echo "${mymap[a]}" # Expected: /path/a
echo "${myorder[0]}" # Expected: a
echo "${#myorder[@]}" # Expected: 2
Problem
When using
local -n(nameref) to reference an indexed array, the+=("value")append operator silently does nothing. The caller's array remains empty.Scalar assignment through nameref works. Associative array key assignment through nameref works. Only indexed array append via
+=is broken.Reproduction
Impact
wedow/harness uses this exact pattern to collect plugin ordering:
What works vs what doesn't
Test cases