1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-05-20 23:41:27 +02:00

51362: Begin documentation for named references.

This commit is contained in:
Bart Schaefer 2023-02-12 11:25:42 -08:00
parent 143e153259
commit 102145b048
5 changed files with 146 additions and 7 deletions

View file

@ -1,5 +1,8 @@
2023-02-12 Bart Schaefer <schaefer@zsh.org>
* 51362: Doc/Zsh/builtins.yo, Doc/Zsh/expn.yo, Doc/Zsh/params.yo,
Doc/Zsh/mod_parameter.yo: Begin documentation for named references.
* 51361: Test/K01nameref.ztst, Test/V10private.ztst: Tests
for 51360.

View file

@ -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.
item(tt(-H))(
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.

View file

@ -1226,6 +1226,9 @@ for parameters with the `hide' flag (tt(-h))
item(tt(hideval))(
for parameters with the `hideval' flag (tt(-H))
)
item(tt(nameref))(
for named references having an empty value (tt(-n))
)
item(tt(special))(
for special parameters defined by the shell
)
@ -1523,6 +1526,77 @@ Include the unmatched portion in the result (the em(R)est).
)
enditem()
subsect(Named References)
cindex(named references)
cindex(namerefs)
cindex(reference variables)
cindex(parameters, nameref)
The command
ifzman()
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
tt(${LPAR()P)tt(RPAR()${LPAR()P)tt(RPAR())var(name)tt(}}).
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:
ifzman()
example(tt(caller=OUTER)
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(})
tt(func caller)
tt(print after func: $caller))
displays the output
ifzman()
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:
ifzman()
example(tt(${)var(name)tt(:|)var(rname)tt(})
tt(${)var(name)tt(:|)var(pname)tt(}))
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)).
subsect(Rules)
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

View file

@ -125,7 +125,7 @@ zmanref(zshexpn)
ifnzman(\
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.
)

View file

@ -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)
endmenu()
@ -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:
ifzman()
example(tt(typeset )var(name)tt(=)var(rname)
tt(print -r -- ${LPAR()P)tt(RPAR())var(name)tt(}))
ifzman()
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
use:
ifzman()
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
ifzman()
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