[Top][All Lists]

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

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

From: Dan Douglas
Subject: Re: declare a="$b" if $a previously set as array
Date: Tue, 16 Dec 2014 01:53:52 -0600
User-agent: KMail/4.14.3 (Linux/3.17.3; KDE/4.14.3; x86_64; ; )

On Sunday, December 14, 2014 02:39:29 PM Chet Ramey wrote:
> And we get to the fundamental issue.  Is it appropriate to require
> arguments to declaration commands to be valid assignment statements when
> the parser sees them, instead of when the builtin sees them, at least
> when using the compound assignment syntax.
> I'm ok with tightening the rules and saying that it is, but it's not
> backwards compatible and changes the behavior of things like
> declare -a foo='(1 2 3)'
> which I imagine plenty of people have used and has been a supported way
> to do compound assignment for many years.

That would be one way but I think this can be solved without going quite
so far. How do you feel about these rules?

        1. If a word that is an argument to declare is parsed as a valid
           assignment, then perform the assignment immediately as it appears
           lexically. If such a word is parsed as a simple assignment (with or
           without an index) then bash treats it as a simple scalar assignment 
           the variable or array element as any ordinary assignment would. If 
           is parsed as an assignment with array initializer list then bash 
           it as such.

        2. Any words that do not parse as valid assignments lexically during 
           1 undergo the usual set of expansions for simple commands and the
           resulting words are saved.

        3. After evaluation of all words from steps 1-2, those that have 
           expansion per 2 are passed as arguments to declare. Declare then 
           each of these arguments, testing for assignments that became valid as
           a result of expansion. During this step, for assignments to variables
           that have an array attribute set, or for all assignments if declare 
           been given the -a or -A option, declare will treat assignments that 
           initializer lists as array assignments accordingly. Otherwise, 
           will treat all assignments as scalar assignments to a variable or 
           element. Words that still fail to parse as valid assignments are an

I think this covers all the bases and is very close to the current behavior
with one exception. All of the problems Stephane and I have brought up deal
with the situation where a word that parses lexically as a scalar assignment
isn't treated as such, so that is the only required change. I don't think
that change will break many scripts.

Some observations:

 * This solves the problem without breaking backwards compatibility and allows
   declare -p output to continue to function.

 * These rules will make the following become compatible with current ksh

         $ ksh -c 'function f { typeset x[1]="(foo bar)"; typeset -p x; }; f'
         typeset -a x=([1]='(foo bar)')

         $ bash -c 'function f { typeset x[1]="(foo bar)"; typeset -p x; }; f'
         declare -a x='([0]="foo" [1]="bar")'

 * Treating words that parse as scalar assignments as scalar assignments is
   consistent with bash's usual treatment of "a[idx]=(foo)". If bash sees
   "declare foo[1]=(foo)", it should print:

   "bash: foo[1]: cannot assign list to array member".

 * Note the fine print in step 3. It deals with this case in bash's current
   behavior and doesn't need to change (-a vs no -a):

        $ bash -c 'x="[4]=foo [6]=bar"; declare -a "y=($x)"; declare -p y'
        declare -a y='([4]="foo" [6]="bar")'

        $ bash -c 'x="[4]=foo [6]=bar"; declare "y=($x)"; declare -p y'
        declare -- y="([4]=foo [6]=bar)"

Dan Douglas

reply via email to

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