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

PATCH and more remarks on parameter expansion docs



Collecting a few threads about parameter expansion here in order to make
some other remarks.

On Jan 1,  7:30am, Han Pingtian wrote:
} Subject: Re: Creating A Clean Environment For Autoloaded Functions
}
} >       # Requires zsh 5.0, otherwise you need a loop
} >       zmodload -u ${(k)modules[(R)loaded]:|existing_modules}
} 
} How could we know that, the "(k)" will be run before ":|" here, please?
} Because "k" will be applied with the subscripting, so it will be before
} the ":|" ?

That's correct.  I've added some mention of this in the patch below.

On Dec 27,  3:08pm, Han Pingtian wrote:
} Subject: Re: splitting in assignment forms of expansion
}
} I think we should say something like this about this feature in the man
} page:
}
}     Note during assignments with the A flag, that splitting is applied 
}     to word in the assignment forms of spec before the assignment to
}     name is performed. This will affects the result.

I added something similar in the patch.

In looking through the parameter flags to see what else may have been
overlooked in the "rules", I found no mention of the (c) and (t) flags.

The (c) flag does what Han Pingtian was asking about in the thread Re:
priority problem of ":|" and ":*" --

    % x=(a b c)
    % print "${#x}" ${(c)#x}
    % 3 5

That is, (c) joins up the array for length purposes even in places where
it would not normally be joined.  I've expanded the doc for this a little
as well, but I didn't explicitly mention it in the rules section because
it only matters in combination with "#".

The (t) flag is an oddball.  If combined with (P) [rule 4], it takes
effect after that name replacement.  However, if *not* combined with
(P), then it takes effect *before* subscripting [rule 3].  Thus:

    % x=path
    % print ${(t)x}
    scalar
    % print ${x[2,4]}
    ath
    % print ${(t)x[2,4]}
    cal
    % print ${(tP)x}
    array-unique-special

I might have expected ${(t)x[2,4]} to print the type of the variable
named "ath", but that isn't what happens.  So I haven't attempted to
work it into the rules, but it's a perfect example of how parameter
expansion syntax lacks well-defined precedence.


Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.148
diff -u -r1.148 expn.yo
--- Doc/Zsh/expn.yo     19 Oct 2012 09:19:08 -0000      1.148
+++ Doc/Zsh/expn.yo     2 Jan 2013 04:57:04 -0000
@@ -748,6 +748,8 @@
 the length in characters of the result instead of
 the result itself.  If var(spec) is an array expression,
 substitute the number of elements of the result.
+This has the side-effect that joining is skipped even in quoted
+forms, which may affect other sub-expressions in var(spec).
 Note that `tt(^)', `tt(=)', and `tt(~)', below, must appear
 to the left of `tt(#)' when these forms are combined.
 )
@@ -870,11 +872,12 @@
 Create an array parameter with `tt(${)...tt(=)...tt(})',
 `tt(${)...tt(:=)...tt(})' or `tt(${)...tt(::=)...tt(})'.
 If this flag is repeated (as in `tt(AA)'), create an associative
-array parameter.  Assignment is made before sorting or padding.
-The var(name) part may be a subscripted range for ordinary
-arrays; the var(word) part em(must) be converted to an array, for
-example by using `tt(${(AA)=)var(name)tt(=)...tt(})' to activate
-field splitting, when creating an associative array.
+array parameter.  Assignment is made before sorting or padding;
+if field splitting is active, the var(word) part is split before
+assignment.  The var(name) part may be a subscripted range for
+ordinary arrays; the var(word) part em(must) be converted to
+an array, for example by using `tt(${(AA)=)var(name)tt(=)...tt(})'
+to activate field splitting, when creating an associative array.
 )
 item(tt(a))(
 Sort in array index order; when combined with `tt(O)' sort in reverse
@@ -884,7 +887,9 @@
 )
 item(tt(c))(
 With tt(${#)var(name)tt(}), count the total number of characters in an array,
-as if the elements were concatenated with spaces between them.
+as if the elements were concatenated with spaces between them.  This is not
+a true join of the array, so other expressions used with this flag may have
+an effect on the elements of the array before it is counted.
 )
 item(tt(C))(
 Capitalize the resulting words.  `Words' in this case refers to sequences
@@ -1308,7 +1313,8 @@
 subscript.  Thus if tt(var) is an array, tt(${var[1][2]}) is the second
 character of the first word, but tt(${var[2,4][2]}) is the entire third
 word (the second word of the range of words two through four of the
-original array).  Any number of subscripts may appear.
+original array).  Any number of subscripts may appear.  Flags such as
+tt((k)) and tt((v)) which alter the result of subscripting are applied.
 )
 item(tt(4.) em(Parameter name replacement))(
 The effect of any tt((P)) flag, which treats the value so far as a
@@ -1316,11 +1322,12 @@
 )
 item(tt(5.) em(Double-quoted joining))(
 If the value after this process is an array, and the substitution
-appears in double quotes, and no tt((@)) flag is present at the current
-level, the words of the value are joined with the first character of the
-parameter tt($IFS), by default a space, between each word (single word
-arrays are not modified).  If the tt((j)) flag is present, that is used for
-joining instead of tt($IFS).
+appears in double quotes, and neither an tt((@)) flag nor a tt(#)
+length operator is present at the current level, then words of the
+value are joined with the first character of the parameter tt($IFS),
+by default a space, between each word (single word arrays are not
+modified).  If the tt((j)) flag is present, that is used for joining
+instead of tt($IFS).
 )
 item(tt(6.) em(Nested subscripting))(
 Any remaining subscripts (i.e. of a nested substitution) are evaluated at



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