[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [3.0.13] declare -a a=('$0')
From: |
Stephane Chazelas |
Subject: |
Re: [3.0.13] declare -a a=('$0') |
Date: |
Tue, 14 Sep 2004 08:18:14 +0100 |
User-agent: |
Mutt/1.5.6i |
On Mon, Sep 13, 2004 at 09:46:30PM +0100, Chet Ramey wrote:
> > declare seems to evaluate its arguments:
>
> It does. The process is actually very regular.
>
> Assignment statements (at least compound assignment statements)
> appearing
> as arguments to `assignment builtins' are parsed specially -- as a
> single
> word. The word becomes one of the arguments to `declare', but marked as
> an assignment.
>
> Each argument to declare is expanded. The words marked as assignments
> (since `declare' is an `assignment builtin') are expanded exactly as
> assignments preceding commands.
That's not clear to me.
bash-3.00$ env -i /usr/local/bin/bash -c 'a=(1 \$PATH) env'
a=(1 $PATH)
PWD=/export/home/chazelas
SHLVL=1
_=/bin/env
(here, $PATH was not expanded). But that makes no sense to pass
an array as an environment variable of a command.
$ ksh -c 'zzz=(1 2) env | grep zzz'
$ zsh -c 'zzz=(1 2) env | grep zzz'
$
> When declare is run, it re-parses the arguments that appear to be
> compound
> assignments. It does the expansion, because at this point there's no
> way
> to tell whether or not the original assignment was quoted.
I'd think that's why it shouldn't be *parsed* as a command (ksh,
whose "type" lies when it pretends "typeset" is a "builtin"). Or
that it should be parsed as any other command and therefore that
array assignments are made impossible.
> declare has to do some reparsing, since it only gets a single argument
> and
> has to somehow split it and understand [index]=value. It uses exactly
> the
> same code as compound assignments preceding commands.
What do you mean by "compound assignments preceding commands"?
bash-3.00$ f() { echo "${a[*]}"; }
bash-3.00$ a=('$$') f
($$)
In zsh:
~$ f() { echo "${a[*]}"; }
~$ a=('$$') f
$$
(same for ksh93).
>
> If you want to avoid this sort of double evaluation, use separate
> compound
> assignment statements.
>
> One reason to let declare do this is to avoid the files=(*) problem
> you beat me up about so heavily earlier.
Sorry if I appeared a bit insisting. The reason I sometimes
posted bug reports twice is that they were never acknowledged,
so that I didn't know wether you missed them or not. Do you
maintain somewhere a list of known bugs or a development version
of bash accessible by CVS?
> If you let the normal
> argument expansion process do the work, you'll end up with arguments
> like [index]=arg if there are files with names of that form, which
> will be handled by assigning to files[index]. If you quote the `*' and
> let declare do the job, you can avoid it.
[...]
Still, that doesn't make much sense to have two different
parsings for
array=(...)
and
declare -a array=(...)
(especially when it's not documented and not compatible between
versions of bash).
declare -a 'array=("$var" *)'
is the same as
array=("$var" *)
You could have had <something>=(...) behave as a strong quote
with a complete parsing that validates the inside as valid shell
code:
a=(')' $$)
parsed as one token containing "a=(')' $$)" (instead of today's
"a=() 1234)").
The simplest, to my mind is not to allow array assignment with
"declare".
$ zsh -c 'declare -a a=()'
zsh: parse error near `()'
$ zsh -c 'declare -a "a=()"'
declare: a: can't assign initial value for array
regards,
Stephane
______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email
______________________________________________________________________