bug-bash
[Top][All Lists]
Advanced

[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 
______________________________________________________________________




reply via email to

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