Date:        Mon, 28 Sep 2026 15:39:32 -0400
    From:        Chet Ramey <[email protected]>
    Message-ID:  <[email protected]>

Not that I care about this, as no-one should be using either
declaration utilities or arrays (IMO), but:

  | The first part is the parser. It has to recognize `declare' as a
  | declaration command so the assignment statement is parsed as a single
  | word, instead of a syntax error. This can be defeated by quoting the
  | `declare' or using variable expansion.

All that is fine.   (It really isn't, what technique is used to write
the command name shouldn't really matter, and it shouldn't be assumed
that the first word is the command name ... does
        foo=bar declare ...
work as a declaration utility?    But POSIX says it is OK, because otherwise
it gets really hard very very quickly).

  | The second part is the word expansion phase. It has to know that it's
  | expanding a declaration utility so it can do things like inhibit word
  | splitting and perform tilde expansion slightly differently.

Yes.   Either the parser passes that info back along with the parse
tree (or whatever bash uses), or the expansion code does the same tests
all over again, either way works.

[And just to be explicit - I know Chet knows this - none of this part,
or anything that follows, happens until the command is actually being
executed, if that never happens, then none of these expansions happen.
The parsing happens even on code that is never executed.]

  | In the case of arrays, it wants to know whether an assignment statement
  | is applying to an indexed or associative array, so it can perform the
  | slightly different expansions needed.

That's OK (though there should be no arrays to care about...)

  | It does this by looking at the next word,
  | which it assumes is an option string if it begins with `-'.

That's OK, though I'd assume it should look at more than just the
first word, in case there are things with the options not all following
a single '-' (declare -g -i ...)

  | This can also be defeated by quoting the word or using variable expansion.

But that's just dumb.   What it should be doing is looking at each arg
in turn, left to right.   If the arg is not in the form name=stuff (where none
of the "name=" is quoted), then it gets expanded the same way it would for
any other command, if it is a name=stuff arg, then the special declaration
type arg processing happens, using the previously expanded words (each having
been tilde, then var/arith/cmdsub expanded, field split, globbed, and finally
quote stripped, with brace expansion and anything else that bash does shoved
in there as well) to supply the context for the var-assign arg now being
expanded.

That just continues to the end of the arg list, each arg in turn gets the
processing needed by it (normal if it isn't a var-assign, special if it is),
in the order the args appear.   Then the declaration utility goes and actually
processes the command as it now exists for whatever results this particular
one produces.

  | This all has the effect of turning a statement like
  |
  | declare -Ag assoc=(one two three four)
  |
  | into the internal equivalent of
  |
  | declare -Ag assoc; assoc=(one two three four)

That's fine, but the same (exactly) should happen for declare "-Ag" assoc=...
or A=-Ag; declare $A assoc=...  or declare "$A" assoc=... or
declare $(echo -Ag) assoc=...  even >-Ag; declare -A? assoc=...

Of course this has to happen for "readonly" as well, in which case it
would need to become
        assoc=(one two three four); readonly -A assoc
or whatever.

What does
        declare -Ar assoc=(one two three four)
turn into?

I'm not sure about the "gin up a shell variable" bit though, the variable
name to use is right there in the arg string.

  | which is how you should be writing these things in the first place.

That I agree with.

  | I've thought about changing the way this code works, and maybe I will
  | someday.

You should, if not today, then this week sometime ... it should be easy,
just an order of processing change in the expansion phase probably.

kre




Reply via email to