bug-bash
[Top][All Lists]
Advanced

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

Re: @K transformation


From: Koichi Murase
Subject: Re: @K transformation
Date: Thu, 19 Aug 2021 19:09:24 +0900

2021年8月19日(木) 18:16 Ilkka Virta <itvirta@gmail.com>:
> On Thu, Aug 19, 2021 at 5:49 AM Koichi Murase <myoga.murase@gmail.com> wrote:
>> FYI, zsh provides this feature for associative arrays with the syntax
>> ${(kv)assoc} or ${(@kv)assoc}. Note that Bash-5.1 already has a
>> similar feature ${array[@]@K}, but the substitution result is quoted
>> so cannot be directly used for the present purpose.
>
>  $ declare -A A=([foo bar]="123 456" [adsf]="456 789")
> $ printf "<%s>\n" "${A[@]@K}"
> <adsf "456 789" "foo bar" "123 456" >
>
> Interesting. I wonder, what's the intended use-case for this?

I don't know the true background, but I guess it is designed as a
variant of ${A[@]@A} where the key-value pairs are compressed in a
single word:

$ printf '<%s>\n' "${A[@]@A}"
<declare>
<-A>
<A=([adsf]="456 789" ["foo bar"]="123 456" )>

The problem of ${A[@]@A} is that it is not so useful when one wants to
define a clone associative array with a different name but with the
same contents as A. Instead, using ${A[@]@K}, one could do

$ declare -A "B=(${A[@]@K})"

to clone the associative array. It is even possible to save the
contents of an associative array in an indexed array as

$ declare -a "saved=(${A[@]@K})"

Hmm..., but for this case, one could actually simply store the
contents in a scalar:

$ saved="${A[*]@K}"

---------

I checked the change history. @K was introduced by commit 5f49ef47d

  
https://git.savannah.gnu.org/cgit/bash.git/commit/?id=5f49ef47d16efb9c8187cc5a193355599567fdd7

where a feature request by Sebastian Gniazdowski

  https://lists.gnu.org/archive/html/bug-bash/2019-07/msg00056.html

was mentioned. In this request, Sebastian has shown the following use case

> declare-A hash=( [key1]=val1 ['key2*[special-chars]']=val2 )
> printf -v serialized "%q " "${*hash[@]}"
> typeset -A deserialized_hash
> eval "deserialized_hash=($serialized)"

Maybe Chet guessed that the serialization is the only use case so that
the new transform can directly produce the serialized result.

Interestingly, Sebastian seems to have suggested ${*hash[@]} being
inspired by zsh's ${(kv)hash[@]}, so I think the original intention of
Sebastian had been that the new syntax would produce keys and values
as separate words.

--
Koichi



reply via email to

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