Open elmehdou opened 1 year ago
Your local scoped map1 variable via func_b
function using func_a1
function ends up in the default global namespace as follows.
$ typeset -p map1 map1[0]
typeset -a map1=(([key2]=val2) )
typeset -A map1[0]=([key2]=val2)
It is difficult at this time for ksh to arrive at your desired nested or multidimensional array structure by simply parsing your one liner nested compound assignment. ksh's default assignment for =()
is a compound variable [-C] not an indexed array [-a] nor associative array [-A]. ksh's current ambiguity in syntax as well as its current parsing methods has ended up in your map1 variable being an indexed array of 1 element containing an associative array of one element.
In this case as you have done in func_a2
function the multidimensional array structure needs to be defined before use so that ksh does not implicitly determine things. See below for a small adjustment to func_a1
defining the top level of your desired multidimensional array to be an associate array and not the default of a compound variable.
function func_a1 {
typeset -n ref=$1
typeset -A ref
ref[key1]=([key2]=val2)
}
$ func_b
Function a1: typeset -A map1=([key1]=([key2]=val2) )
Function a2: typeset -A map2=([key1]=([key2]=val2) )
$ typeset -p map1 map2
$
Or perhaps, we might set variable map1 to be an associate array from the start.
function func_a1 {
typeset -n ref=$1
ref[key1]=([key2]=val2)
}
function func_b {
typeset -A map1
func_a1 map1
echo "Function a1: $(typeset -p map1)"
typeset map2
func_a2 map2
echo "Function a2: $(typeset -p map2)"
}
$ func_b
Function a1: typeset -A map1=([key1]=([key2]=val2) )
Function a2: typeset -A map2=([key1]=([key2]=val2) )
$ typeset -p map1 map2
$
See issue #148 for more insights.
I have to say, it's quite frustrating when such important features are still unstable. The company I work at relies heavily on ksh for complex operations, so having to find workarounds for each feature that's supposed to make my life easier and scripts cleaner is very scary. Thanks for you feedback.
I can understand your frustrations but I do not share your sentiment that ksh has important unstable features.
Hopefully, as your proficiency with ksh continues to grow; your life will become easier and far less scary. From my viewpoint, most other command line scripting languages lack multidimensional array support so I consider ksh's array support as absolutely beneficial allowing me to program in a more concise and flexible manner than having to create workarounds with one-dimensional arrays only.
This does look like a bug. The following version of the reproducer makes it slightly more obvious that the two functions should be equivalent:
function func_a1 {
typeset -n ref=$1
typeset -A ref=(
[key1]=(
[key2]=val2
)
)
}
function func_a2 {
typeset -n ref=$1
typeset -A ref
ref[key1]=(
[key2]=val2
)
}
function func_b {
typeset map1
func_a1 map1
echo "Function a1: $(typeset -p map1)"
typeset map2
func_a2 map2
echo "Function a2: $(typeset -p map2)"
}
func_b
Output:
Function a1: typeset -A map1=()
Function a2: typeset -A map2=([key1]=([key2]=val2) )
Expected output:
Function a1: typeset -A map1=([key1]=([key2]=val2) )
Function a2: typeset -A map2=([key1]=([key2]=val2) )
Additional testing results based on new reproducer:
Container type | func_a1 Test | Result | Success |
---|---|---|---|
nested associative arrays | typeset -A ref=([key1]=([key2]=val2) ) | typeset -A map1=() | No |
nested indexed arrays | typeset -a ref=( (a b) (c d) ) | typeset -a map1 | No |
compound variables with indexed arrays | typeset -C ref=( a=(c d); b=(e f) ) | typeset -C map1=(typeset -a a=(c d);typeset -a b=(e f);) | Yes |
nested compound variables | typeset -C ref=( a=(c=e; ); b=(d=f;) ) | ksh: func_b[3]: func_a1: line 3: map1.a.c=e: no parent | No |
2d fixed indexed array | typeset -a ref[2][2]; ref=( (a b) (c d) ) | Memory fault or Segmentation fault | No |
An example of pasted code change above:
function func_a1 {
typeset -n ref=$1
typeset -a ref[2][2]; ref=( (a b) (c d) )
}
func_b
Setting a nested associative arrays in one go fails on references: