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

[PATCH 3/3] Documentation for named references

"make info" works on my Ubuntu desktop but I haven't scrutinized the
man page results.

Proofing appreciated.
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 56428a714..64c47346f 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -2037,6 +2037,20 @@ To initialize a parameter var(param) to a command output and mark it readonly,
 use tt(typeset -r )var(param) or tt(readonly )var(param) after the parameter
 assignment statement.
+cindex(named reference)
+cindex(reference, named)
+The flag tt(-n) creates a em(named reference) to another parameter.
+The second parameter need not exist at the time the reference is
+created.  No other attribute flags may be used in conjunction with
+tt(-n).  The var(name) assigned-to may not be an array element nor use
+a subscript, but the var(value) assigned may be any valid parameter
+name syntax, even a subscripted array element (incuding an associative
+array element) or an array slice, which is evaluated when the named
+reference is expanded.
+See ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)) and
+ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)) for details of the
+behavior of named references.
 If no attribute flags are given, and either no var(name) arguments are
 present or the flag tt(+m) is used, then each parameter name printed is
 preceded by a list of the attributes of that parameter (tt(array),
@@ -2242,9 +2256,9 @@ automatically given the tt(-h) attribute to avoid name clashes.
 Hide value: specifies that tt(typeset) will not display the value of the
 parameter when listing parameters; the display for such parameters is
-always as if the `tt(PLUS())' flag had been given.  Use of the parameter is
-in other respects normal, and the option does not apply if the parameter is
-specified by name, or by pattern with the tt(-m) option.  This is on by
+always as if the `tt(PLUS())' flag were given, but use of the parameter is
+in other respects normal.  This effect does not apply when the parameter is
+specified by name or by pattern with the tt(-m) option.  This is on by
 default for the parameters in the tt(zsh/parameter) and tt(zsh/mapfile)
 modules.  Note, however, that unlike the tt(-h) flag this is also useful
 for non-special parameters.
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index fd5443b20..ff6087cac 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -1226,6 +1226,9 @@ for parameters with the `hide' flag (tt(-h))
 for parameters with the `hideval' flag (tt(-H))
+for named references having an empty value (tt(-n))
 for special parameters defined by the shell
@@ -1523,6 +1526,77 @@ Include the unmatched portion in the result (the em(R)est).
+subsect(Named References)
+cindex(named references)
+cindex(reference variables)
+cindex(parameters, nameref)
+The command
+indent(tt(typeset -n )var(pname)tt(=)var(rname))
+initializes a parameter var(pname) as a reference to a second
+parameter var(rname).  With the few exceptions described here, when
+var(pname) is used in any of the expansion forms described above, the
+parameter var(rname) is expanded instead.  This is similar to the
+action of the `tt((P))' expansion flag, but when var(rname) has itself
+been declared a named reference, that third parameter referenced by
+var(pname) is also expanded, and so on.  With `tt((P))' this must be
+done explicitly, so for example
+Unlike `tt((P))', named references in substitutions that perform
+assignment, such as tt(${)var(pname)tt(::=)var(word)tt(}), do not
+create new arrays when var(rname) is in the form of an array element
+or slice and no such array (or associative array) is presently set.
+This includes arrays declared, but not initialized, when the option
+tt(TYPESET_TO_UNSET) is in effect.  The var(word) is substituted but
+no assignment occurs.
+Also unlike `tt((P))' named references always expand parameters at
+the scope in which var(rname) existed when `tt(typeset -n)' was
+called.  This can be used to expand or assign parameters from an
+earlier scope even if a local of the same name has been declared at
+a later scope.  Example:
+tt(func LPAR()RPAR() {)
+tt(  print before local: $caller)
+tt(  typeset -n outer=$1)
+tt(  local caller=INNER)
+tt(  print by reference: $outer)
+tt(  outer=RESULT)
+tt(func caller)
+tt(print after func: $caller))
+displays the output
+example(tt(before local: OUTER)
+tt(by reference: OUTER)
+tt(after func: RESULT))
+When var(rname) includes an array subscript, the subscript expression
+is interpreted at the time tt(${)var(pname)tt(}) is expanded.  Any
+form of subscript is allowed, including those that select individual
+elements, substrings of scalar strings, or multiple elements as with
+array slices or the `tt((i))', `tt((I))', `tt((r))', `tt((R))' and
+`tt((w))' subscript flags.
+When var(rname) is an array (but not an array element or slice), the
+named reference may also be used in substitutions requiring an
+var(arrayname), so these are equivalent:
+Expansions of the form `tt(${LPAR()t)tt(RPAR())var(pname)tt(})' expand
+the type information of var(rname), unless var(rname) is empty, in which
+case `tt(nameref)' is expanded, or when no variable var(rname) exists,
+in which case the expansion is empty.
+See also ifzman(zmanref(zshparam))ifnzman(noderef(Parameters)).
 cindex(parameter expansion rules)
 cindex(rules, parameter expansion)
@@ -1545,12 +1619,16 @@ 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
+Note that, unless the `tt((P))' flag or a named reference 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,
+tt(${foo}).  When a named reference or the `tt((P))' flag is used 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}).
+When both a named reference and the `tt((P))' flag appear, the named
+reference is resolved before `tt((P))' is applied.
 At each nested level of substitution, the substituted words undergo all
 forms of single-word substitution (i.e. not filename generation), including
diff --git a/Doc/Zsh/mod_parameter.yo b/Doc/Zsh/mod_parameter.yo
index 18fd3606e..0e89d65c8 100644
--- a/Doc/Zsh/mod_parameter.yo
+++ b/Doc/Zsh/mod_parameter.yo
@@ -125,7 +125,7 @@ zmanref(zshexpn)
 noderef(Parameter Expansion)
-.  The value may also be `tt(undefined)' indicating a parameter that
+. The value may also be `tt(undefined)' indicating a parameter that
 may be autoloaded from a module but has not yet been referenced.
 Setting or unsetting keys in this array is not possible.
diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index 55009c6de..2dfd5bd14 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -80,6 +80,7 @@ startmenu()
 menu(Array Parameters)
 menu(Positional Parameters)
 menu(Local Parameters)
+menu(Named References)
 menu(Parameters Set By The Shell)
 menu(Parameters Used By The Shell)
@@ -592,7 +593,7 @@ array assignment of the form `var(n)tt(=LPAR())var(value) ...tt(RPAR())' is
 allowed, and has the effect of shifting all the values at positions greater
 than var(n) by as many positions as necessary to accommodate the new values.
-texinode(Local Parameters)(Parameters Set By The Shell)(Positional Parameters)(Parameters)
+texinode(Local Parameters)(Named References)(Positional Parameters)(Parameters)
 sect(Local Parameters)
 Shell function executions delimit scopes for shell parameters.
 (Parameters are dynamically scoped.)  The tt(typeset) builtin, and its
@@ -626,6 +627,49 @@ find the programs in tt(/new/directory) inside a function.
 Note that the restriction in older versions of zsh that local parameters
 were never exported has been removed.
+cindex(named references)
+cindex(references, named)
+texinode(Named References)(Parameters Set By The Shell)(Local Parameters)(Parameters)
+sect(Named References)
+Zsh supports two different mechanisms for indirect parameter referencing:
+example(tt(typeset )var(name)tt(=)var(rname)
+tt(print -r -- ${LPAR()P)tt(RPAR())var(name)tt(}))
+example(tt(typeset -n )var(pname)tt(=)var(rname)
+tt(print -r -- ${)var(pname)tt(}))
+The `tt((P))' flag method is older and should be used when a script
+needs to be backwards-compatible.  This is described fully in
+ifzman(zmanref(zshexpn))ifnzman(noderef(Parameter Expansion)).
+When a em(named reference) is created with `tt(typeset -n)', all uses
+of var(pname) in assignments and expansions instead assign to or
+expand var(rname).  This also applies to `tt(unset )var(pname)' and to
+most subsequent uses of `tt(typeset)' with the exception of
+`tt(typeset +n)', so to remove a named reference it is necessary to
+example(tt(typeset +n )var(pname)
+tt(unset )var(pname))
+When `tt(typeset -n )var(pname)tt(=)var(rname)' appears in a given
+(global or function) scope, `tt(${)var(pname)tt(})' refers to
+var(rname) in the scope of the tt(typeset) command.  This differs
+from ksh93 where the scope used is that of var(rname) even if the
+current var(rname) would be found in a surrounding scope.
+em(This is a misfeature.)
+An empty reference such as one of
+example(tt(typeset -n )var(pname)
+tt(typeset -n )var(pname)tt(=)
+tt(typeset -n )var(pname)tt(=""))
+acts as a placeholder.  The first non-empty assignment to var(pname)
+initializes the reference, and subsequently any expansions of, or
+assignments to, var(pname) act on the referenced parameter.
 texinode(Parameters Set By The Shell)(Parameters Used By The Shell)(Local Parameters)(Parameters)
 sect(Parameters Set By The Shell)
 In the parameter lists that follow, the mark `<S>' indicates that the

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