zsh-users
 help / color / mirror / code / Atom feed
* (z) expansion flag do not always return an array
@ 2021-11-29 15:31 Vincent Bernat
  2021-11-29 16:34 ` Roman Perepelitsa
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Vincent Bernat @ 2021-11-29 15:31 UTC (permalink / raw)
  To: zsh-users

Hey!

The (z) expansion flag is documented to return an array, but this is not
the case if we have only one word:

 16:24 ❱ print -l ${${(z)${:-word1}}[1]}
w
 16:24 ❱ print -l ${${(z)${:-word1 word2}}[1]}
word1

This can be worked around with A:

 16:29 ❱ print -l ${${(Az)${:-word1}}[1]}
word1
 16:29 ❱ print -l ${${(Az)${:-word1 word2}}[1]}
word1

But older versions of Zsh does not have that. Is there another way? Is
there an easy way to know if something is an array or a string? I am
using subscripting for that but maybe there are better ways.

-- 
Don't over-comment.
            - The Elements of Programming Style (Kernighan & Plauger)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: (z) expansion flag do not always return an array
  2021-11-29 15:31 (z) expansion flag do not always return an array Vincent Bernat
@ 2021-11-29 16:34 ` Roman Perepelitsa
  2021-11-29 17:44   ` Vincent Bernat
  2021-11-29 16:50 ` Lawrence Velázquez
  2021-11-29 19:43 ` Bart Schaefer
  2 siblings, 1 reply; 8+ messages in thread
From: Roman Perepelitsa @ 2021-11-29 16:34 UTC (permalink / raw)
  To: Vincent Bernat; +Cc: Zsh Users

On Mon, Nov 29, 2021 at 4:32 PM Vincent Bernat <bernat@luffy.cx> wrote:
>
> Is there an easy way to know if something is an array or a string?
> I am  using subscripting for that but maybe there are better ways.

If you had a parameter, you could use ${(t)foo} or $parameters[foo] to
find its type. However, if you had a parameter you wouldn't have this
problem to begin with.

  foo=(${(z)...})

Here foo is always an array.

Roman.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: (z) expansion flag do not always return an array
  2021-11-29 15:31 (z) expansion flag do not always return an array Vincent Bernat
  2021-11-29 16:34 ` Roman Perepelitsa
@ 2021-11-29 16:50 ` Lawrence Velázquez
  2021-11-29 17:03   ` Peter Stephenson
                     ` (2 more replies)
  2021-11-29 19:43 ` Bart Schaefer
  2 siblings, 3 replies; 8+ messages in thread
From: Lawrence Velázquez @ 2021-11-29 16:50 UTC (permalink / raw)
  To: Vincent Bernat; +Cc: zsh-users

On Mon, Nov 29, 2021, at 10:31 AM, Vincent Bernat wrote:
> The (z) expansion flag is documented to return an array

Is it?  The 5.8 man page does not mention "array" even once.

    z   Split the result of the expansion into words using shell
        parsing to find the words, i.e. taking into account any
        quoting in the value.  Comments are not treated specially but
        as ordinary strings, similar to interactive shells with the
        INTERACTIVE_COMMENTS option unset (however, see the Z flag
        below for related options)

        Note that this is done very late, even later than the `(s)'
        flag.  So to access single words in the result use nested
        expansions as in `${${(z)foo}[2]}'.  Likewise, to remove the
        quotes in the resulting words use `${(Q)${(z)foo}}'.

-- 
vq


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: (z) expansion flag do not always return an array
  2021-11-29 16:50 ` Lawrence Velázquez
@ 2021-11-29 17:03   ` Peter Stephenson
  2021-11-29 17:43   ` Vincent Bernat
  2021-11-29 17:45   ` Bart Schaefer
  2 siblings, 0 replies; 8+ messages in thread
From: Peter Stephenson @ 2021-11-29 17:03 UTC (permalink / raw)
  To: zsh-users


> On 29 November 2021 at 16:50 Lawrence Velázquez <larryv@zsh.org> wrote:
> On Mon, Nov 29, 2021, at 10:31 AM, Vincent Bernat wrote:
> > The (z) expansion flag is documented to return an array
> 
> Is it?  The 5.8 man page does not mention "array" even once.

Indeed, there's not really any notion of "returning an array".  There's
just the question of how something is treated at a particular part
of parameter expansion.  Forcing something to be treated in a
particular way by tweaking the expansion is possible, forcing
a particular value always to be treated in some way regardless
of context isn't, to the best of my knowledge.  The context always
has the last say --- consider quoting, and the flags to circumvent
quoting, for example.  They're all (over the top metaphor coming)
breadcrumbs to lead us of the labyrinth that's ended up at a
corner.

More generally, return values and explicit expression typing are things
shells, including zsh, are very bad at; it's particularly annoying with
zsh, however, owing to the complexities you can get into, and
nested parameters are one of the worst examples.

Feel free to find a counterexample, obviously.

pws


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: (z) expansion flag do not always return an array
  2021-11-29 16:50 ` Lawrence Velázquez
  2021-11-29 17:03   ` Peter Stephenson
@ 2021-11-29 17:43   ` Vincent Bernat
  2021-11-29 17:45   ` Bart Schaefer
  2 siblings, 0 replies; 8+ messages in thread
From: Vincent Bernat @ 2021-11-29 17:43 UTC (permalink / raw)
  To: Lawrence Velázquez; +Cc: zsh-users

 ❦ 29 November 2021 11:50 -05, Lawrence Velázquez:

>> The (z) expansion flag is documented to return an array
>
> Is it?  The 5.8 man page does not mention "array" even once.
>
>     z   Split the result of the expansion into words using shell
>         parsing to find the words, i.e. taking into account any
>         quoting in the value.  Comments are not treated specially but
>         as ordinary strings, similar to interactive shells with the
>         INTERACTIVE_COMMENTS option unset (however, see the Z flag
>         below for related options)
>
>         Note that this is done very late, even later than the `(s)'
>         flag.  So to access single words in the result use nested
>         expansions as in `${${(z)foo}[2]}'.  Likewise, to remove the
>         quotes in the resulting words use `${(Q)${(z)foo}}'.

When I read "split", I read "into an array". I must miss something.
Also, it works when there is something to split, but not when there is
only one word.
-- 
Don't use conditional branches as a substitute for a logical expression.
            - The Elements of Programming Style (Kernighan & Plauger)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: (z) expansion flag do not always return an array
  2021-11-29 16:34 ` Roman Perepelitsa
@ 2021-11-29 17:44   ` Vincent Bernat
  0 siblings, 0 replies; 8+ messages in thread
From: Vincent Bernat @ 2021-11-29 17:44 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Zsh Users

 ❦ 29 November 2021 17:34 +01, Roman Perepelitsa:

>> Is there an easy way to know if something is an array or a string?
>> I am  using subscripting for that but maybe there are better ways.
>
> If you had a parameter, you could use ${(t)foo} or $parameters[foo] to
> find its type. However, if you had a parameter you wouldn't have this
> problem to begin with.

Thanks for the tips!

>   foo=(${(z)...})
>
> Here foo is always an array.

Yes, that's what I have done.
-- 
Let the machine do the dirty work.
            - The Elements of Programming Style (Kernighan & Plauger)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: (z) expansion flag do not always return an array
  2021-11-29 16:50 ` Lawrence Velázquez
  2021-11-29 17:03   ` Peter Stephenson
  2021-11-29 17:43   ` Vincent Bernat
@ 2021-11-29 17:45   ` Bart Schaefer
  2 siblings, 0 replies; 8+ messages in thread
From: Bart Schaefer @ 2021-11-29 17:45 UTC (permalink / raw)
  To: Lawrence Velázquez; +Cc: Vincent Bernat, Zsh Users

On Mon, Nov 29, 2021 at 8:51 AM Lawrence Velázquez <larryv@zsh.org> wrote:
>
> On Mon, Nov 29, 2021, at 10:31 AM, Vincent Bernat wrote:
> > The (z) expansion flag is documented to return an array
>
> Is it?  The 5.8 man page does not mention "array" even once.

True, but "split" usually implies $@ -variety results.  Also:

>         [...].  So to access single words in the result use nested
>         expansions as in `${${(z)foo}[2]}'.

That would lead one to believe that ${${(z)foo}[1]} also returns a
single word, but as PWS notes the context may alter that.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: (z) expansion flag do not always return an array
  2021-11-29 15:31 (z) expansion flag do not always return an array Vincent Bernat
  2021-11-29 16:34 ` Roman Perepelitsa
  2021-11-29 16:50 ` Lawrence Velázquez
@ 2021-11-29 19:43 ` Bart Schaefer
  2 siblings, 0 replies; 8+ messages in thread
From: Bart Schaefer @ 2021-11-29 19:43 UTC (permalink / raw)
  To: Vincent Bernat; +Cc: Zsh Users

On Mon, Nov 29, 2021 at 7:31 AM Vincent Bernat <bernat@luffy.cx> wrote:
>
>  16:29 ❱ print -l ${${(Az)${:-word1}}[1]}
> word1
>
> But older versions of Zsh does not have that. Is there another way?

The only way I can come up with is to append a dummy extra element; instead of

 ${${(z)something}[1]}

use

 ${${(z)${:-$something \\}}[1]}


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-11-29 19:44 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-29 15:31 (z) expansion flag do not always return an array Vincent Bernat
2021-11-29 16:34 ` Roman Perepelitsa
2021-11-29 17:44   ` Vincent Bernat
2021-11-29 16:50 ` Lawrence Velázquez
2021-11-29 17:03   ` Peter Stephenson
2021-11-29 17:43   ` Vincent Bernat
2021-11-29 17:45   ` Bart Schaefer
2021-11-29 19:43 ` Bart Schaefer

Code repositories for project(s) associated with this inbox:

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).