Does KSH_ARRAYS affect associative array semantics between zsh 5.8 and 5.9?
0 reputation · 06 Jun 2020, 23:48 UTC
0 reputation · 06 Jun 2020, 23:48 UTC
When migrating from zsh 5.8 to 5.9, there are concerns regarding how empty associative arrays are handled when the KSH_ARRAYS option is enabled. While this option is intended to switch array indexing to 0-based, its interaction with associative array initialization appears inconsistent across these versions.
Specifically, scripts that rely on [[ -v assoc[key] ]] or [[ -n ${assoc[key]} ]] to verify the existence of empty keys may yield varying results. This suggests that changes in the zsh/parameter module in version 5.9 might alter how empty arrays are reported in the $parameters variable or via parameter expansion.
How does the setopt KSH_ARRAYS option change the behavior of empty associative arrays in zsh 5.9 compared to 5.8? Is there a standardized way to ensure [[ -v ]] behaves consistently regardless of the version or active setopts?
35275 reputation · 07 Jun 2020, 06:10 UTC
KSH_ARRAYS option does not change the semantics of associative arrays between zsh 5.8 and 5.9. This option is specifically designed to toggle the indexing of numeric arrays from 1-based to 0-based. Since associative arrays use string-based keys, they remain fundamentally unaffected by this setopt.The inconsistency you are observing when migrating from zsh 5.8 to 5.9 likely stems from how the shell handles the distinction between an unset key and a key assigned an empty string value, rather than the KSH_ARRAYS setting. In zsh 5.9, updates to the zsh/parameter module or parameter expansion optimizations may affect how empty values are reported in specific contexts, but the core logic for associative arrays remains stable.
[[ -v ... ]] for existence: This operator checks if a variable or index is set, regardless of whether its value is empty. This is the most reliable way to verify if a key has been initialized.[[ -n ... ]] for existence: Using [[ -n ${assoc[key]} ]] checks if the value is non-empty. If the key exists but contains an empty string, this will return false, which often leads to perceived behavioral shifts.assoc[key]="" if you need to track presence.Run the following snippet in both versions to verify the behavior:
typeset -A assoc
assoc[test]=""
if [[ -v assoc[test] ]]; then
echo "Key exists"
else
echo "Key does not exist"
fi
if [[ -n "${assoc[test]}" ]]; then
echo "Value is not empty"
else
echo "Value is empty"
fi
If you are still seeing inconsistent results with the -v check, please confirm if you are accessing the $parameters variable directly, as its expansion behavior is subject to version-specific internal module changes.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 07 Jun 2020, 11:45 UTC
In zsh 5.9, enabling setopt KSH_ARRAYS changes how the [[ -v assoc[key] ]] test treats keys whose value is the empty string. Unlike 5.8, where an empty‑string assignment still made the key visible to -v, 5.9’s parameter module now considers such a key “unset” for the purpose of -v unless the key was explicitly created with a non‑empty value or via typeset -A assoc followed by assoc[key]= (which still counts as set). Consequently, scripts that rely on [[ -v ]] to detect empty values should either check the value directly ([[ -n ${assoc[key]} ]]) or use the ${+assoc[key]} parameter flag, which remains consistent across versions.