help-bash
[Top][All Lists]
Advanced

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

Re: How do we get state of a flag in set -o ...


From: Greg Wooledge
Subject: Re: How do we get state of a flag in set -o ...
Date: Tue, 11 Jul 2023 20:34:41 -0400

On Tue, Jul 11, 2023 at 07:57:38PM -0400, Grisha Levit wrote:
> On Tue, Jul 11, 2023, 18:47 Greg Wooledge <greg@wooledge.org> wrote:
> 
> > Now, obviously you could throw in 'eval' into the picture, but then you
> > would need to use "${list[@]@Q}" or something.
> >
> 
> I think the canonical way is to use the @K transformation, making sure the
> rhs of the assignment is quoted:
> 
> $ declare -A A=('k $1' 'v $1')
> $ declare -A B="(${A[@]@K})"
> $ declare -p B
> declare -A B=(["k \$1"]="v \$1" )

Whatever you're doing here, it's not intuitive to me at all.  If I'm
going to initialize an associative array from key/value pairs that are
in another array, then that other array is going to be *indexed*.
Otherwise, I already *have* an associative array, so why would I want
a second one?  If I just wanted to copy an array, I'd use declare -p
output and change the array name.  Or use a loop over the indices.

With a list:

unicorn:~$ declare -p list
declare -a list=([0]="key1" [1]="" [2]="key2" [3]="[" [4]="key3" [5]="]" 
[6]="key4" [7]="\$(date >&2)")
unicorn:~$ unset -v hash; declare -A hash
unicorn:~$ hash="(${list[@]@K})"
unicorn:~$ declare -p hash
declare -A hash=([0]="(0 \"key1\" 1 \"\" 2 \"key2\" 3 \"[\" 4 \"key3\" 5 \"]\" 
6 \"key4\" 7 \"\\\$(date >&2)\")" )

OK, so we can't use a regular assignment, but I didn't really expect
that to work.

I guess you're using "declare -A" as a form of "eval light" or something.

unicorn:~$ declare -A hash="(${list[@]@K})"
unicorn:~$ declare -p hash
declare -A hash=([7]="\$(date >&2)" [6]="key4" [5]="]" [4]="key3" [3]="[" 
[2]="key2" [1]="" [0]="key1" )

That's definitely not what I wanted.

If you've got a list (indexed array) that contains alternating keys and
values, how does your approach use that to initialize an associative array?
Or does it simply not do that at all?

I don't think @K is what I want here, because it's injecting the numeric
indices into the list.  I don't want those.  I just want *the list*.
Does this work...?

unicorn:~$ declare -A hash="(${list[@]@Q})"
unicorn:~$ declare -p hash
declare -A hash=([key4]="\$(date >&2)" [key2]="[" [key3]="]" [key1]="" )

Yeah, that looks better.  It's using declare -A in place of eval, and
because it's got a "declare" in it, it potentially changes the scope of
the variable that's being assigned, unlike a regular eval.

I suppose the "declare" method looks slightly nicer if and only if you
were already planning to declare -A the associative array at the same
time you're initializing it.  Otherwise, the "eval" is better, because
it doesn't mess with the variable scope.

Regarding the @K expansion, that looks like a good tool for serializing
an existing associative array to a list/stream.  But for un-serializing
the list or stream back into an AA, you'd want @Q (if you read it into
an indexed array) or just "$string" if you read it into a string.



reply via email to

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