diff --git a/crates/bashkit/src/interpreter/mod.rs b/crates/bashkit/src/interpreter/mod.rs index 2c683556..b17c8daf 100644 --- a/crates/bashkit/src/interpreter/mod.rs +++ b/crates/bashkit/src/interpreter/mod.rs @@ -6312,12 +6312,14 @@ impl Interpreter { .strip_suffix("[@]") .or_else(|| name.strip_suffix("[*]")) { + // Resolve nameref: if arr_name is a nameref, follow it to the target + let resolved_arr_name = self.resolve_nameref(arr_name); let sep = if is_star { self.get_ifs_separator() } else { " ".to_string() }; - if let Some(arr) = self.assoc_arrays.get(arr_name) { + if let Some(arr) = self.assoc_arrays.get(resolved_arr_name) { let is_set = !arr.is_empty(); let mut keys: Vec<_> = arr.keys().collect(); keys.sort(); @@ -6325,7 +6327,7 @@ impl Interpreter { keys.iter().filter_map(|k| arr.get(*k).cloned()).collect(); return (is_set, values.join(&sep)); } - if let Some(arr) = self.arrays.get(arr_name) { + if let Some(arr) = self.arrays.get(resolved_arr_name) { let is_set = !arr.is_empty(); let mut indices: Vec<_> = arr.keys().collect(); indices.sort(); @@ -6343,15 +6345,17 @@ impl Interpreter { && name.ends_with(']') { let arr_name = &name[..bracket]; + // Resolve nameref: if arr_name is a nameref, follow it to the target + let resolved_arr_name = self.resolve_nameref(arr_name); let key = &name[bracket + 1..name.len() - 1]; - if let Some(arr) = self.assoc_arrays.get(arr_name) { + if let Some(arr) = self.assoc_arrays.get(resolved_arr_name) { let expanded_key = self.expand_variable_or_literal(key); return match arr.get(&expanded_key) { Some(v) => (true, v.clone()), None => (false, String::new()), }; } - if let Some(arr) = self.arrays.get(arr_name) + if let Some(arr) = self.arrays.get(resolved_arr_name) && let Ok(idx) = key.parse::() { return match arr.get(&idx) { diff --git a/crates/bashkit/tests/spec_cases/bash/nameref.test.sh b/crates/bashkit/tests/spec_cases/bash/nameref.test.sh index 86eb968f..e6d4c586 100644 --- a/crates/bashkit/tests/spec_cases/bash/nameref.test.sh +++ b/crates/bashkit/tests/spec_cases/bash/nameref.test.sh @@ -264,3 +264,57 @@ echo "$result" ### expect computed ### end + +### nameref_assoc_default_value +# ${ref[key]:-default} through nameref to assoc array (issue #801) +declare -A m=([x]=1 [y]=2) +f() { + local -n ref="$1" + echo "${ref[x]:-EMPTY}" + echo "${ref[y]:-EMPTY}" + echo "${ref[z]:-EMPTY}" +} +f m +### expect +1 +2 +EMPTY +### end + +### nameref_assoc_replacement +# ${ref[key]:+alt} through nameref to assoc array +declare -A m=([a]=val) +f() { + local -n ref="$1" + echo "${ref[a]:+found}" + echo "${ref[missing]:+found}" +} +f m +### expect +found + +### end + +### nameref_assoc_subscript_at_default +# ${ref[@]:-default} through nameref to assoc array +declare -A m=([k]=v) +f() { + local -n ref="$1" + echo "${ref[@]:-EMPTY}" +} +f m +### expect +v +### end + +### nameref_assoc_subscript_at_empty +# ${ref[@]:-default} through nameref to empty assoc array +declare -A m +f() { + local -n ref="$1" + echo "${ref[@]:-EMPTY}" +} +f m +### expect +EMPTY +### end