zsh-users
 help / color / mirror / code / Atom feed
* Splitting into a one element array
@ 2015-09-14 20:06 Jesper Nygårds
  2015-09-14 20:26 ` ZyX
  2015-09-14 21:46 ` Bart Schaefer
  0 siblings, 2 replies; 4+ messages in thread
From: Jesper Nygårds @ 2015-09-14 20:06 UTC (permalink / raw)
  To: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 977 bytes --]

I am writing a function where I want to split the $LBUFFER on whitespace,
and then handle the last element in the resulting array. My initial attempt
looked like this:

local dir=${${(z)LBUFFER}[-1]}

This works if $LBUFFER contains more than one word, but fails if it is one
word only. I tested the behavior with the following function:

trysplit() {
    local astring="aaa bbb"
    print -l ${=astring}
    print
    print -l ${${=astring}[-1]}
    print
    local cstring="ccc"
    print -l ${=cstring}
    print
    print -l ${${=cstring}[-1]}
}

with this result:

% trysplit
aaa
bbb

bbb

ccc

c

So, my interpretation of the above is that IF the split results in only one
word, the result is not handled as an array with one element, but as a
regular string. And then only the first letter of the $cstring is printed.

Is there some way to handle this that I have missed, or do I need to check
the split result for size, and then treat the one-element case differently?

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

* Re: Splitting into a one element array
  2015-09-14 20:06 Splitting into a one element array Jesper Nygårds
@ 2015-09-14 20:26 ` ZyX
  2015-09-14 21:46 ` Bart Schaefer
  1 sibling, 0 replies; 4+ messages in thread
From: ZyX @ 2015-09-14 20:26 UTC (permalink / raw)
  To: Jesper Nygårds, Zsh Users

14.09.2015, 23:07, "Jesper Nygårds" <jesper.nygards@gmail.com>:
> I am writing a function where I want to split the $LBUFFER on whitespace,
> and then handle the last element in the resulting array. My initial attempt
> looked like this:
>
> local dir=${${(z)LBUFFER}[-1]}
>
> This works if $LBUFFER contains more than one word, but fails if it is one
> word only. I tested the behavior with the following function:
>
> trysplit() {
>     local astring="aaa bbb"
>     print -l ${=astring}
>     print
>     print -l ${${=astring}[-1]}
>     print
>     local cstring="ccc"
>     print -l ${=cstring}
>     print
>     print -l ${${=cstring}[-1]}
> }
>
> with this result:
>
> % trysplit
> aaa
> bbb
>
> bbb
>
> ccc
>
> c
>
> So, my interpretation of the above is that IF the split results in only one
> word, the result is not handled as an array with one element, but as a
> regular string. And then only the first letter of the $cstring is printed.
>
> Is there some way to handle this that I have missed, or do I need to check
> the split result for size, and then treat the one-element case differently?

I have a workaround for this:

    local -a arr
    arr=( ${(z)LBUFFER} )
    local dir=${arr[-1]}


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

* Re: Splitting into a one element array
  2015-09-14 20:06 Splitting into a one element array Jesper Nygårds
  2015-09-14 20:26 ` ZyX
@ 2015-09-14 21:46 ` Bart Schaefer
  2015-09-15  6:15   ` Jesper Nygårds
  1 sibling, 1 reply; 4+ messages in thread
From: Bart Schaefer @ 2015-09-14 21:46 UTC (permalink / raw)
  To: Zsh Users

On Sep 14, 10:06pm, Jesper Nygards wrote:
} Subject: Splitting into a one element array
} I am writing a function where I want to split the $LBUFFER on whitespace,
} and then handle the last element in the resulting array. My initial attempt
} looked like this:
} 
} local dir=${${(z)LBUFFER}[-1]}
} 
} This works if $LBUFFER contains more than one word, but fails if it is one
} word only.

Yes, this is a side-effect of nested expansion working "inside out"; if
if there's nothing for ${(z)...} to split, the result becomes a scalar
before the context one level up is even considered.

For the case of splitting on spaces you can fix this with a subscript
flag as in ${LBUFFER[(w)-1]}, but because (z) splits on syntax rather
than on spaces there's no simple corresponding flag for "subscript on
shell words".

So the most readable way is probably the local array that ZyX suggested,
but if you really want a single nested expansion:

    ${${(z)LBUFFER}[(wps:$'\0':)-1]}

This works because the subscript flag [(w)] is only active when applied
to a scalar, so (ps:$'\0':) only applies when (z) returns a single word,
which won't contain a $'\0' byte so is not split further.


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

* Re: Splitting into a one element array
  2015-09-14 21:46 ` Bart Schaefer
@ 2015-09-15  6:15   ` Jesper Nygårds
  0 siblings, 0 replies; 4+ messages in thread
From: Jesper Nygårds @ 2015-09-15  6:15 UTC (permalink / raw)
  To: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 1354 bytes --]

Ah yes, now I see. Thank you both!


On Mon, Sep 14, 2015 at 11:46 PM, Bart Schaefer <schaefer@brasslantern.com>
wrote:

> On Sep 14, 10:06pm, Jesper Nygards wrote:
> } Subject: Splitting into a one element array
> } I am writing a function where I want to split the $LBUFFER on whitespace,
> } and then handle the last element in the resulting array. My initial
> attempt
> } looked like this:
> }
> } local dir=${${(z)LBUFFER}[-1]}
> }
> } This works if $LBUFFER contains more than one word, but fails if it is
> one
> } word only.
>
> Yes, this is a side-effect of nested expansion working "inside out"; if
> if there's nothing for ${(z)...} to split, the result becomes a scalar
> before the context one level up is even considered.
>
> For the case of splitting on spaces you can fix this with a subscript
> flag as in ${LBUFFER[(w)-1]}, but because (z) splits on syntax rather
> than on spaces there's no simple corresponding flag for "subscript on
> shell words".
>
> So the most readable way is probably the local array that ZyX suggested,
> but if you really want a single nested expansion:
>
>     ${${(z)LBUFFER}[(wps:$'\0':)-1]}
>
> This works because the subscript flag [(w)] is only active when applied
> to a scalar, so (ps:$'\0':) only applies when (z) returns a single word,
> which won't contain a $'\0' byte so is not split further.
>

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

end of thread, other threads:[~2015-09-15  6:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-14 20:06 Splitting into a one element array Jesper Nygårds
2015-09-14 20:26 ` ZyX
2015-09-14 21:46 ` Bart Schaefer
2015-09-15  6:15   ` Jesper Nygårds

Code repositories for project(s) associated with this public 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).