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

Re: triviality regarding $# counts



# It's not a zebra, it's a horse with painted stripes!
# If you want a COPY ... yes, a Xerox copy:
% fff=( "${(@f)ddd}" )

What? No.  Why do you keep bringing (f) into this? That flag has nothing to do with copying; in fact it intentionally changes things: anywhere there used to be a single string containing a newline,you get two strings instead. 

But if you drop the f, you do get your Xerox copy:

% fff=( "${(@)ddd}" )

Would it be nicer if you could just do fff=$ddd and not have to include the parens and quotes and @? Sure. You could even make a case that it should work that way, since we're in Zshland where $ddd expands to the whole array instead of a single element. But that's not the way assignment works. Though, as I said, if the array has no empty elements, you can get away with just fff=($ddd).






On Sun, Apr 14, 2024 at 9:24 AM Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:


On 2024-04-13 21:57, Bart Schaefer wrote:
Because zsh does not split parameter expansions by default, $ary and
$ary[*] and $ary[@] are equivalent when not quoted, as Lawrence
demonstrated.

However, in all three of those cases, empty elements are typically
discarded, as they would be in a shell that defaults to splitting.
That's why "$ary[@]" is still useful:  It quotes each element
individually, so empty elements are preserved.

(Aside, in bash and ksh, $ary is equivalent to ${ary[0]}, not to
${ary[*]}.  A little oddly, this is also true for their associative
arrays, that is, the value for key 0 is used.)
I know it's far too late to fret this stuff, still it's interesting to contemplate these design level issues.  P.F. did the right thing not splitting by default but he should have left the empties in by default too, IMHO.  Options should be positive not negative as a fundamental principle.  Don't do helpful things automatically, and force me to stop you from doing them.  Much better to leave things alone, and if I want, say, empty elements removed, I'll ask for them to be removed.  A=B should mean that A is identical to B, not B with blanks removed, nor sorted, nor capitalized, nor duplicates removed, nor checked for spelling, nor ... nothing. 

"$ary[@]" should be the default with some ${(?)...} flag to indicate that I'd like blanks removed or  duplicates or ... whatever massaging I'd want.  Cool that all those manipulations are available of course, but as Raymond Sensei  (E. S. Raymond) explains so well, the 'doctrine of least surprise' should prevail.  Equals equals equals, not 'equals minus blanks'.  So we have:

aaa=( "${(@f)bbb}" )  

... which is code fighting itself.  The quotes normally mean 'join together' but they also mean 'preserve spaces' and so then '(@f)' contradicts the joining so we retain multiple elements.  IMHO it should look like this:

aaa=( $bbb )

Equals equals equals. 

But as we have  it:

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

% print $ddd                    
abc     def ghi     jkl mno     pqr

% fff=( $ddd )        

% print $fff
abc     def ghi     jkl mno     pqr

# Looks ok, donit? But don't be a chump:

% typeset -p ddd; typeset -p fff
typeset -a ddd=( '' abc '' $'\tdef ghi' $'\tjkl mno' '' $'\tpqr' '' )
typeset -a fff=( abc $'\tdef ghi' $'\tjkl mno' $'\tpqr' )

# It's not a zebra, it's a horse with painted stripes!
# If you want a COPY ... yes, a Xerox copy:

% fff=( "${(@f)ddd}" )

% typeset -p ddd; typeset -p fff
typeset -a ddd=( '' abc '' $'\tdef ghi' $'\tjkl mno' '' $'\tpqr' '' )
typeset -a fff=( '' abc '' $'\tdef ghi' $'\tjkl mno' '' $'\tpqr' '' )

# That's a COPY ... and don't even think about a simpler way, we are on this earth to suffer.

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

Just sayin', I know there's nothing to be done about it now. 





--
Mark J. Reed <markjreed@xxxxxxxxx>


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