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

PATCH: Re: Parameter expansion/substitution rules



Sven Wischnowsky wrote:
> Bart Schaefer wrote:
> 
> > The new section on expansion rules should mention when the (e) and (P)
> > flags kick in.
> 
> (P) is used very early, after subscripting, before other
> modifications.
> With (eP), the (e) is still aplied at the end, as always (i.e. there
> is no special treatment for the combination).

Here is the documentation for that.

I've also separated out rule 1. into two parts: the first now just
indicates the rules for nested substitutions, and the second the rule for
subscripting bare parameter names.  Before, I had combined these to show
that bare parameter names were treated differently from subscripting nested
substitutions.  But I think it makes more sense with these as distinct
rules, so I've mentioned that the other subscripting applies to returned
nested substitutions and made that a separate rule too.

I've also mentioned double subscripting of arrays, e.g. $path[1][2].

I've also added names for the rules, which makes them more convenient to
refer to and easier to remember.

It also looked like the rules for when you need braces were not explained,
so I've added that.  I may have missed out some cases.  Note this is
described where the ${...} form is first mentioned, not in the main rules
section which is complicated enough without worrying about braces.

I've resisted the temptation to add any more commentary since it's wordy
enough as it is, but if anybody has any other examples which could shed
light on this they could be added to the Examples section.

There's also the question of when things like $~ and $# are applied, which
I haven't mentioned.

--- Doc/Zsh/expn.yo.ep	Mon Mar 22 18:44:20 1999
+++ Doc/Zsh/expn.yo	Wed Mar 24 17:08:07 1999
@@ -329,7 +329,12 @@
 The value, if any, of the parameter var(name) is substituted.
 The braces are required if the expansion is to be followed by
 a letter, digit, or underscore that is not to be interpreted
-as part of var(name).
+as part of var(name).  In addition, more complicated forms of substitution
+usually require the braces to be present; exceptions, which only apply if
+the option tt(KSH_ARRAYS) is not set, are a single subscript or any colon
+modifiers appearing after the name, or any of the characters tt(^), tt(=),
+tt(~), tt(#) or tt(+) appearing before the name, all of which work with or
+without braces.
 
 If var(name) is an array parameter, then the value of each
 element of var(name) is substituted, one element per word.
@@ -494,12 +499,7 @@
 possible to perform nested operations:  tt(${${foo#head}%tail})
 substitutes the value of tt($foo) with both tt(head) and tt(tail)
 deleted.  The form with tt($LPAR())...tt(RPAR()) is often useful in
-combination with the flags described next; see the example below.
-
-Note that when nested parameter expansion takes place the flags are em(not)
-propagated back.  Each level of expansion uses three factors: whether it
-is in double quotes, what flags it has been provided with, and whether the
-value it has is a scalar or an array.  Some examples are given below.
+combination with the flags described next; see the examples below.
 
 subsect(Parameter Expansion Flags)
 cindex(parameter expansion flags)
@@ -703,57 +703,82 @@
 
 subsect(Rules)
 
-Here is a summary of the rules for substitution.  Some particular examples
-are given below.  Note that the Zsh Development Group accepts em(no
-responsibility) for any brain damage which may occur during the reading of
-the following rules.
+Here is a summary of the rules for substitution; this assumes that braces
+are present around the substitution, i.e. tt(${...}).  Some particular
+examples are given below.  Note that the Zsh Development Group accepts
+em(no responsibility) for any brain damage which may occur during the
+reading of the following rules.
 
 startitem()
-item(tt(1.))(
+item(tt(1.) em(Nested Substitution))(
 If multiple nested tt(${...}) forms are present, substitution is
 performed from the inside outwards.  At each level, the substitution takes
 account of whether the current value is a scalar or an array, whether the
 whole substitution is in double quotes, and what flags are supplied to the
-current level of substitution.  If the value is a raw parameter reference
-with a subscript, such as tt(${)var(var)tt([3]}), the effect of
-subscripting is applied directly to the parameter.  The value passed back
-to an enclosing substitution is always an array, which however will consist
-of one word if the value was not itself an array.
+current level of substitution; the flags are not propagated up to enclosing
+substitutions.  The value passed back to an enclosing substitution is
+always an array, which however will consist of one word if the value was
+not itself an array.  All the following steps take place where applicable
+at all levels of substitution.
+)
+item(tt(2.) em(Parameter Subscripting))(
+If the value is a raw parameter reference with a subscript, such as
+tt(${)var(var)tt([3]}), the effect of subscripting is applied directly to
+the parameter.  If the parameter is an array, any second subscript,
+indexing on the character in the word, may appear,
+e.g. tt(${)var(var)tt([1][2]}).
+)
+item(tt(3.) em(Parameter Name Replacement))(
+The effect of any tt((P)) flag, which treats the value so far as a
+parameter name and replaces it with the corresponding value, is applied.
 )
-item(tt(2.))(
+item(tt(4.) 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). Any remaining subscript is evaluated at
-this point, based on whether the value is an array or a scalar.
+joining instead of tt($IFS).
+)
+item(tt(5.) em(Nested Subscripting))(
+Any remaining subscript (i.e. of a nested substitution) is evaluated at
+this point, based on whether the value is an array or a scalar; if it was
+an array, a second subscript for the character in the word may also appear.
 )
-item(tt(3.))(
+item(tt(6.) em(Modifiers))(
 Any modifiers, as specified by a trailing tt(#), tt(%), tt(/)
 (possibly doubled) or by a set of modifiers of the form tt(:...) (see
 noderef(Modifiers) in noderef(History Expansion)), are applied to the words
 of the value at this level.
 )
-item(tt(4.))(
+item(tt(7.) em(Forced Joining))(
 If the tt((j)) flag is present, or no tt((j)) flag is present but
-the string is to be split as given by rules tt(5.) or tt(6.), and joining
-did not take place at step tt(2.), any words in the value are joined
+the string is to be split as given by rules tt(8.) or tt(9.), and joining
+did not take place at step tt(4.), any words in the value are joined
 together using the given string or the first character of tt($IFS) if none.
 Note that the tt((F)) flag implicitly supplies a string for joining in this
 manner.
 )
-item(tt(5.))(
+item(tt(8.) em(Forced Splitting))(
 If one of the tt((s)) or tt((f)) flags are present, or the tt(=)
 specifier was present (e.g. tt(${=)var(var)tt(})), the word is split on
 occurrences of the specified string, or (for tt(=) with neither of the two
 flags present) any of the characters in tt($IFS).
 )
-item(tt(6.))(
+item(tt(9.) em(Shell Word Splitting))(
 If no tt((s)), tt((f)) or tt(=) was given, but the word is not
 quoted and the option tt(SH_WORD_SPLIT) is set, the word is split on
-occurrences of any of the characters in tt($IFS).  Note that all steps,
-including this one, take place at all levels of a nested substitution.
+occurrences of any of the characters in tt($IFS).  Note this step, too,
+take place at all levels of a nested substitution.
+)
+item(tt(10.) em(Re-Evaluation))(
+Any tt((e)) flag is applied to the value, forcing it to be re-examined for
+new parameter substitutions, but also for command and arithmetic
+substitutions.
+)
+item(tt(11.) em(Padding))(
+Any padding of the value by the tt(LPAR()l.)var(fill)tt(.RPAR()) or
+tt(LPAR()r.)var(fill)tt(.RPAR()) flags is applied.
 )
 enditem()
 
-- 
Peter Stephenson <pws@xxxxxxxxxxxxxxxxx>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy



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