bug-bash
[Top][All Lists]
Advanced

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

Re: declare a="$b" if $a previously set as array


From: Stephane Chazelas
Subject: Re: declare a="$b" if $a previously set as array
Date: Sun, 14 Dec 2014 20:48:45 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

2014-12-14 14:57:15 -0500, Chet Ramey:
[...]
> Well, I don't think it's particularly a syntax issue.  It's the question
> I wrote in my previous message: how much further should we move compound
> assignment away from the execution semantics associated with builtins.
[...]

IMO, the ksh behaviour is the closest one can get to a
consistent approach and still allow assignments to arrays:

act like an assignment modifier except when the arguments don't
form valid assignment (simple command parsing then, and only
scalar assignments for arguments that contain "=").

declare var=(1 2 3)

declares and sets an array only as long as "var=(" and ")" are
litteral (as in not the result of any expansion) and unquoted
and "var" is a valid identifier.

declare "var="(1 2 3)
or
declare ""var=(1 2 3)

would be syntax errors.

declare var=$foo

doesn't perform word splitting but assigns the content of $foo
as a string to $var (or ${var[0]} if an array, or ${var["0"]} if
a hash).

declare "var="$foo
declare ""var=$foo
declare $foo=$foo

would perform split+glob on $foo. (parsed like a normal command)

declare var="("[123]=bar")"

parsed like a scalar assignment (no globbing on that unquoted
[123], no hash/array assignment.

In short, all the assignments you can do without declare should
work the same with declare. And things that would not be treated
as an assignment without declare (like \a=foo, ${1+a=$1}...) are
parsed normally as arguments to declare, and declare by itself
only does scalar assignments including to array members, never
array or hash assignment.

ksh supports:

$ ksh -c 'typeset a[1]=(1 2 3); typeset -p a'
typeset -a a=([1]=(1 2 3) )

but that's because it supports nested arrays. It makes
sense for bash to just return an error there (as it does
already).

declare would still end up do some indirect evaluation as part
of arithmetic evaluation in array subscript:

foo='a[0$(uname>&2)]=foo'
declare "$foo"

would still run uname before assigning foo to a[0]. I'd rather
it doesn't do that (only expand $(...) when litteral), but if we
fix it here, we'd need to fix it everywhere else as well.

Does that make sense?

BTW:

$ bash -c 'declare a[1]="(1 2 3)"; declare -p a'
declare -a a='([0]="1" [1]="2" [2]="3")'

$ bash -c 'declare a+=([1]="1 2 3"); declare -p a'
bash: line 0: declare: `a+': not a valid identifier
declare -a a='([1]="1 2 3")'

How do I do ATM if I want a[1] to contain "(1 2 3)" with
declare?

-- 
Stephane



reply via email to

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