Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Belaboring substitution syntax



On Thu, Nov 17, 2022 at 3:32 AM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
>
> On Wed, Nov 16, 2022 at 6:15 AM Roman Perepelitsa
> <roman.perepelitsa@xxxxxxxxx> wrote:
> >
> > On Wed, Nov 16, 2022 at 3:09 PM Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
> > >
> > > "${array[@]}" ... Read: protect the elements of this array, do any expansions within them, but do NOT combine them ??
> >
> > No, this just expands the array to all its elements.
>
> In the base cases, you can think of it as "if I can't see it, nothing
> happens to it."  The exceptions only occur when you start adding
> parameter flags like ${(e)array[@]}.

If I didn't know that ${array[@]} without quotes does not in general
expand to the array's elements, I could be confused by this exchange,
so I'll post some examples for Ray's benefit.

This does nothing (the array's content is unchanged):

    array=("${array[@]}")

This may change the content of the array:

    array=(${array[@]})

The content of the array is changed by this statement in two ways:

1. All empty elements are removed.
2. If sh_word_split is set, elements of the array are split on $IFS.

To demonstrate (1):

    % () {
      emulate -L zsh
      local array=('' 'foo bar')
      typeset -p array
      array=(${array[@]})
      typeset -p array
    }

    typeset -a array=( '' 'foo bar' )
    typeset -a array=( 'foo bar' )

To demonstrate (2):

    % () {
      emulate -L zsh -o sh_word_split
      local array=('' 'foo bar')
      typeset -a array=( 'foo bar' )
      array=(${array[@]})
      typeset -p array
    }

    typeset -a array=( '' 'foo bar' )
    typeset -a array=( foo bar )

In short, "${array[@]}" expands to array elements just like "$scalar"
expands to the scalar's value. Versions without quotes are more
complex, for they may transform the value in various ways.

Additionally, unless ksh_arrays is set (it's unset by default), these
two are equivalent:

    "${array[@]}"
    "${(@)array}"

And these four are equivalent:

    ${array[@]}
    ${(@)array}
    ${array}
    $array

Roman.




Messages sorted by: Reverse Date, Date, Thread, Author