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

Re: psychiatric help



On Sat, Apr 4, 2026 at 4:24 PM Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
>
> Problem is when the command tail has to be passed on to another function

By "the command tail" you mean the positional parameters? $*, $@, or
$1, $2, $3, ... ?

> internally so I have no chance to edit it.  Hard spaces are going to
> become soft spaces.

"Hard" (previously quoted) spaces only become "soft" (unquoted) spaces
when, well, you don't quote them.

On top of that, though, in zsh, quoted spaces only become unquoted
when you explicitly unquote them.  There are a bunch of ways to do
that, but the most common are
- setopt sh_word_split
- ${=var} (temporarily sh_word_split)
- eval

I'm reasonably sure you're not doing sh_word_split, but based on your
history of questions you have a habit of using eval.

I think you're also a bit unclear on the concept of arrays and of
using double-quotes.

$* and $@ (and $argv) are arrays, having the same elements.  Unless
you mean for their value to be converted to a string, you should use
array operations on them.  That means you should NOT do

out=${@//\ /\\ }

because that is a string (scalar) assignment, so all the elements of
the $@ array get concatenated together into a single string as the
value of $out.  That puts you in the position of having to split $out
apart again to use the array elements.  Given your focus on keeping
the backslashes, I'd be willing to bet you're doing that with eval.

If you need to copy $@ (et al.) into another variable, use array syntax:

out=( $@ )

That preserves all your "hard" spaces in each of the elements of the
array $out.  Of course if you need to do some other manipulation of
the individual element values, there may be complications, but the
basic idea is to stop needlessly converting arrays to strings and
back.

A refresher on $* and $@ and quoting ...

These are equivalent (assuming no_sh_word_split):
ary=( $* )
ary=( $@ )
ary=( "$@" )

These are also equivalent:

str=$*
str=$@
str="$*"

Notice how "$@" and "$*" differ.

"$*" is like "$1 $2 $3 ..."
"$@" is like "$1" "$2" "$3" ...

That last example preserves "hard" spaces even when sh_word_split is
set, so if you think your code might run in a context where you don't
know, use "$@" for safety.

Consequently if you have

function tail_call {
   print -rC1 -- "$@"
}

function call {
  tail_call "$@"
}

You can be sure that

call test\ ?

will, in your example directory, output

test a
test b

> I always thought that permitting spaces in
> designators was a bad idea from the getgo. Should never have been permitted.

Sadly, I don't know what you mean by "designators".




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