Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: nested ${(P)} (formerly SHWORDSPLIT and leading spaces)
- X-seq: zsh-workers 37115
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: Re: PATCH: nested ${(P)} (formerly SHWORDSPLIT and leading spaces)
- Date: Sat, 14 Nov 2015 21:14:13 -0800
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern_com.20150623.gappssmtp.com; s=20150623; h=from:message-id:date:in-reply-to:comments:references:to:subject :mime-version:mime-version:content-type; bh=aoyaxkomT8VRednoZ1sUiC5gvhwC6vxy9y5+Af0OtLI=; b=XHTIOM/qFlKFLDEfPeq38lONYgQfwxYI71QnW6tkmty42+NGzP7TpHpbWXI1FdT3I3 3pwoSYinYsPRegwFuOXSm4KrXXA8Q77MoZKUVfjSfW7fJQSqwrdAew0tsPBF5m9r3gQ0 AHL7/wLcf5KLyU2EsSxnDKvR/AhJCGFUyuxvnWYzrVxGfH18BnvJ4Be+Glytg2RTlRll sHUmDqUHTotjgeIn+fACyLX9uFxBXXcuAasSgKbBnnXkb0aVOqXLRR5ynv1+t+dM2p1Z C45gBrpUhhFV3mguZUPqpQFrLfXkD2rFMeMzjMXTJrmFnCFxLQbZeDTSxJ2raJBdve0g hiEg==
- In-reply-to: <0faa0ee3-303a-4cb5-a270-d3d1787accf1@email.android.com>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <0faa0ee3-303a-4cb5-a270-d3d1787accf1@email.android.com>
[PWS mis-addressed his original message to "zsh-hackers" so I've included
it in its entirety below.]
On Nov 14, 10:31pm, Peter Stephenson wrote:
}
} On 14 Nov 2015 18:51, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
} >
} > 1. there is an outer ${...} around the ${(P)...} expansion
} > 2. the (P) is combined with one of (l), (r), or (j).
} >
} > If there's only one level, ${(Pr.N.)...} et al. work as expected.
}
} Yes, that's also deliberate. As there is no outer layer here, the code
} executed is identical to before (the only alternative would be yet a
} third type of behaviour; we can0x02BCt fake up a whole surrounding
} layer) . If the (P) is surrounded by a an outer layer, the effect
} mentioned before hsppens: the inner layer refers to the name, and
} the outer to the substituted value. As I already said, if we are
} separating the effects of layers to get a sensible effect with e. g.
} subscripts, there is no question of flags in the inner layer having an
} effect on the value. It is not just a minor side effect.
}
} pws
OK ... but this means we definitely need some updates to the "Rules"
section. For example, rule #2 says that effect of "typeset -u"
should happen before the effects of (P) at rule #4. This appears to
have been incorrect at least as far back as zsh 4.2 -- the name
deref'd by (P) is the raw value of the variable, though whether the
internal flags might change the raw value is different in 4.2 -- so
given:
torch% ARRAY=(foo bar)
torch% array=(one two)
torch% name=array
torch% typeset -u name
torch% print $name
ARRAY
In zsh-5.1.1:
% print ${(P)name}
one two
% print ${${(P)name}}
one two
With zsh-5.1.1-160-gd5ba08a, nesting the (P) makes -u take effect:
torch% print ${(P)name}
one two
torch% print ${${(P)name}}
foo bar
Aside: It's also worth remembering that the LRZul "internal flags"
have never worked for arrays; you can set them and they're remembered
but they have no effect on the individual array elements.
Subscripting #3 applies before (P) #4 as described, even when (P) is
within a nested substitution, but applies after #2 when there is no
(P) involved, so we somehow have to explain how the order of 2/3/4
changes when a nested (P) is introduced.
Here's a stab at it (and also a fix for _git, which appears to be the
only contributed function that relied on the former behavior).
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 3dfd604..614185e 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -5244,7 +5244,7 @@ _git_commands () {
for cmdtype in aliases $cmdtypes; do
local -a ${cmdtype}_d
(( $#disp )) && set -A ${cmdtype}_d \
- ${${(Pr.COLUMNS-4.)cmdtype/(#s)(#m)[^:]##:/${(r.len.)MATCH[1,-2]} $sep }%% #}
+ ${${(r.COLUMNS-4.)${(P)cmdtype}/(#s)(#m)[^:]##:/${(r.len.)MATCH[1,-2]} $sep }%% #}
alts+=( "${cmdtype//_/-}:${${cmdtype//_/ }%%(e|)s}:compadd ${(e)disp} -a ${cmdtype}_m" )
done
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 4c373d1..6f08d7d 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -1380,9 +1380,13 @@ outermost. The flags are not propagated up to enclosing
substitutions; the nested substitution will return either a scalar or an
array as determined by the flags, possibly adjusted for quoting. All the
following steps take place where applicable at all levels of substitution.
-Note that, unless the `tt((P))' flag is present, the flags and any subscripts
-apply directly to the value of the nested substitution; for example, the
-expansion tt(${${foo}}) behaves exactly the same as tt(${foo}).
+
+Note that, unless the `tt((P))' flag is present, the flags and any
+subscripts apply directly to the value of the nested substitution; for
+example, the expansion tt(${${foo}}) behaves exactly the same as
+tt(${foo}). When the `tt((P))' flag is present in a nested substitution,
+the other substitution rules are applied to the value em(before) it is
+interpreted as a name, so tt(${${(P)foo}}) may differ from tt(${(P)foo}).
At each nested level of substitution, the substituted words undergo all
forms of single-word substitution (i.e. not filename generation), including
@@ -1400,6 +1404,12 @@ in particular the tt(L), tt(R), tt(Z), tt(u) and tt(l) flags for padding
and capitalization, are applied directly to the parameter value.
Note these flags are options to the command, e.g. `tt(typeset -Z)';
they are not the same as the flags used within parameter substitutions.
+
+At the outermost level of substitution, the `tt((P))' flag ignores these
+transformations and uses the unmodified value of the parameter as the name
+to be replaced. This is usually the desired behavior because padding may
+make the value syntactically illegal as a parameter name, but if
+capitalization changes are desired, use the tt(${${(P)foo}}) form.
)
item(tt(3.) em(Parameter subscripting))(
If the value is a raw parameter reference with a subscript, such as
@@ -1413,8 +1423,10 @@ 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
-parameter name and replaces it with the corresponding value, is applied.
+At the outermost level of nesting only, 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. This replacement occurs later if the
+tt((P)) flag appears in a nested substitution.
)
item(tt(5.) em(Double-quoted joining))(
If the value after this process is an array, and the substitution
@@ -1534,6 +1546,11 @@ Strictly speaking, the removal happens later as the same happens with
other forms of substitution; the point to note here is simply that
it occurs after any of the above parameter operations.
)
+item(tt(25.) em(Parameter name replacement))(
+If the `tt((P))' flag is present and this has not yet been done, the value
+so far is looked up as a parameter name. Errors may occur if the value is
+neither a valid identifier nor an identifier plus subscript expression.
+)
enditem()
subsect(Examples)
Messages sorted by:
Reverse Date,
Date,
Thread,
Author