Re: more splitting

Ray Andrews <[email protected]> Thu, 16 Apr 2026 20:50:34 -0700
Newsgroups gmane.comp.shells.zsh.devel,gmane.comp.shells.zsh.user
Message-ID <[email protected]>

On 2026-04-16 04:11, Philippe Altherr wrote:
>
> function hex()
> {
>   if (($#)); then
>     echo "--- Front door --------------"
>     print -rC1 -- ${(q+)@}
>     echo "\n-----------------------------\n"
>     for element ("$@") print -rn -- $element | od -vAx -tx1 -tc
>   fi
>   if [[ -p /dev/fd/0 ]]; then
>     local var c; while read -u 0 -k 1 c; do var+=$c; done
>     echo "--- Back door ---------------"
>     print -rC1 -- ${(q+)var}
>     echo "\n-----------------------------\n"
>     for element ("$var") print -rn -- $element | od -vAx -tx1 -tc
>   fi
> }
>
> The line "local var c; while read -u 0 -k 1 c; do var+=$c; done" is 
> rather verbose and most likely very inefficient but it's the only way 
> I know to fully read what's at the back door including any trailing 
> newline characters.
Speed is never an issue, the only thing that matters is getting an 
absolutely clear understanding of how the array was built.

Thanks Philippe, that has a pleasing symetry.  The way you capture the 
pipe is elegant, it has a rightness about it.  I'd not have imagined 
that one could use the front door and the back door at the same time.  
And, all else equal it's probably more othodox to pass the value of the 
variable than the name. If it's at the front door the splitting is 
retained.

It really is impossible to know from the pipe version where the input 
array was split, the information no longer exists.  Still, there is an 
ambiguity:

% var=("a b" c$'\n''d e f'' ''g h' ij); hhex $var
--- Front door --------------
'a b'
$'c\nd e f g h'
ij

-----------------------------

000000  61  20  62
          a       b
000003
000000  63  0a  64  20  65  20  66  20  67  20  68
          c  \n   d       e       f       g       h
00000b
000000  69  6a
          i   j
000002

% var2=( ${(f)var} ); hhex $var2
--- Front door --------------
'a b c'
'd e f g h ij'

-----------------------------

000000  61  20  62  20  63
          a       b       c
000005
000000  64  20  65  20  66  20  67  20  68  20  69  6a
          d       e       f       g       h       i   j
00000c

It seems that the splitting char is always removed, thus one can't look 
at $var2 and determine that it was created via split on newlines, one 
might just as well conclude that it was split on spaces, with a space 
between 'c' and 'd' instead of a newline.  This seems to me an 
imperfection, tho obviously one would have to go back to the 70s to have 
done anything about it.  In the interests of perfect information, I 
wonder if there's any way that even the 'od' output could inform us that 
the output of $var2 is an array split on newlines?  I suspect that 'od' 
has no way of knowing.