bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

"${assoc[@]@k}" doesn't get expanded to separate words within compound a


From: Zachary Santer
Subject: "${assoc[@]@k}" doesn't get expanded to separate words within compound assignment syntax
Date: Tue, 19 Mar 2024 23:18:10 -0400

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: msys
Compiler: gcc
Compilation CFLAGS: -march=nocona -msahf -mtune=generic -O2 -pipe
-D_STATIC_BUILD
uname output: MINGW64_NT-10.0-19045 Zack2021HPPavilion 3.4.10.x86_64
2024-02-10 08:39 UTC x86_64 Msys
Machine Type: x86_64-pc-msys

Bash Version: 5.2
Patch Level: 26
Release Status: release

Description:

The man page's descriptions of ${var@K} and ${var@k}:
K Produces a possibly-quoted version of the value of parameter, except
that it prints the values of indexed and associative arrays as a
sequence of quoted key-value pairs (see Arrays above).
k Like the K transformation, but expands the keys and values of
indexed and associative arrays to separate words after word splitting.

In the section on Arrays, we see:
When assigning to an associative array, the words in a compound
assignment may be either assignment statements, for which the
subscript is required, or a list of words that is interpreted as a
sequence of alternating keys and values: name=( key1 value1 key2
value2 ...). These are treated identically to name=( [key1]=value1
[key2]=value2 ...). The first word in the list determines how the
remaining words are interpreted; all assignments in a list must be of
the same type. When using key/value pairs, the keys may not be missing
or empty; a final missing value is treated like the empty string.

The "${assoc[@]@k}" transformation doesn't leave the separate
key/value words quoted. I'm not sure if the phrasing of the
documentation implies that it would or not.

As such, I would expect that
$ declare -A assoc_2=( "${assoc_1[@]@k}" )
would create assoc_2 as a duplicate of assoc_1. However, we see that
the entire expansion becomes the key for a single array element, with
its value being the empty string.

Repeat-By:

$ declare -A assoc_1=( [key 0]='value 0' [key 1]='value 1' [key
2]='value 2' [key 3]='value 3' )
$ unset assoc_2
$ declare -A assoc_2
$ printf '|%s|\n' "${assoc_1[*]@k}"
|key 2 value 2 key 3 value 3 key 0 value 0 key 1 value 1|
# All one word. Makes sense.
$ assoc_2=( "${assoc_1[*]@k}" )
$ declare -p assoc_2
declare -A assoc_2=(["key 2 value 2 key 3 value 3 key 0 value 0 key 1
value 1"]="" )
# Still makes sense.
$ printf '|%s|\n' "${assoc_1[@]@k}"
|key 2|
|value 2|
|key 3|
|value 3|
|key 0|
|value 0|
|key 1|
|value 1|
# Got expanded to separate words, like it's supposed to.
$ assoc_2=( "${assoc_1[@]@k}" )
$ declare -p assoc_2
declare -A assoc_2=(["key 2 value 2 key 3 value 3 key 0 value 0 key 1
value 1"]="" )
# Here, it did not.

If it were up to me, "${scalar@k}" wouldn't do anything different than
"${scalar}" and "${assoc[@]@K}" would expand to separate, quoted
words.

$ scalar='some words'
$ printf '|%s|\n' "${scalar@K}"
|'some words'|
$ printf '|%s|\n' "${scalar@k}"
|'some words'|
# This is inconsistent with what the @k parameter transformation does
with an array.
$ printf '|%s|\n' "${assoc_1[*]@K}"
|"key 2" "value 2" "key 3" "value 3" "key 0" "value 0" "key 1" "value 1" |
$ printf '|%s|\n' "${assoc_1[@]@K}"
|"key 2" "value 2" "key 3" "value 3" "key 0" "value 0" "key 1" "value 1" |
# Quoted [*] and [@] array expansions do things differently everywhere
else I can think of.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]