zsh-workers
 help / color / mirror / code / Atom feed
* [PATCH 3/3] Documentation for named references
@ 2023-02-06  2:26 Bart Schaefer
  2023-02-07  0:56 ` Daniel Shahaf
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2023-02-06  2:26 UTC (permalink / raw)
  To: Zsh hackers list

[-- Attachment #1: Type: text/plain, Size: 110 bytes --]

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

Proofing appreciated.

[-- Attachment #2: nameref-3-doc.txt --]
[-- Type: text/plain, Size: 10365 bytes --]

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.
 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.
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))
 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
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)
 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.
 )
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)
 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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/3] Documentation for named references
  2023-02-06  2:26 [PATCH 3/3] Documentation for named references Bart Schaefer
@ 2023-02-07  0:56 ` Daniel Shahaf
  2023-02-07  3:25   ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Daniel Shahaf @ 2023-02-07  0:56 UTC (permalink / raw)
  To: Zsh hackers list

Bart Schaefer wrote on Sun, Feb 05, 2023 at 18:26:50 -0800:
> +++ b/Doc/Zsh/builtins.yo
> @@ -2037,6 +2037,20 @@ To initialize a parameter var(param) to a command output and mark it readonly,
> +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

s/assigned-to/assigned to/

> +a subscript, but the var(value) assigned may be any valid parameter
> +name syntax, even a subscripted array element (incuding an associative

"incuding"

> +++ b/Doc/Zsh/expn.yo
> @@ -1523,6 +1526,77 @@ Include the unmatched portion in the result (the em(R)est).
> +subsect(Named References)
> +cindex(named references)
> +cindex(namerefs)
> +cindex(reference variables)
> +cindex(parameters, nameref)
> +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 `tt(nameref)'"?

> @@ -1545,12 +1619,16 @@ substitutions; the nested substitution will return either a scalar or an
> +When both a named reference and the `tt((P))' flag appear, the named
> +reference is resolved before `tt((P))' is applied.

Add a test for this last sentence?

> +++ b/Doc/Zsh/params.yo
> @@ -626,6 +627,49 @@ find the programs in tt(/new/directory) inside a function.
> +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)).
> +

WDYT of documenting somewhere in the manual namerefs are new in 5.10?

> +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.)

Does "This is a misfeature" mean "This may change in the future to be
compatible with ksh93"?

> +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)

s/Local Parameters/Named References/

Cheers,

Daniel
(public service announcement: we have *.yo syntax highlighting for Vim
in our tree)


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/3] Documentation for named references
  2023-02-07  0:56 ` Daniel Shahaf
@ 2023-02-07  3:25   ` Bart Schaefer
  2023-02-07 10:51     ` Daniel Shahaf
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2023-02-07  3:25 UTC (permalink / raw)
  To: Zsh hackers list

On Mon, Feb 6, 2023 at 4:57 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> Bart Schaefer wrote on Sun, Feb 05, 2023 at 18:26:50 -0800:

> > +tt(-n).  The var(name) assigned-to may not be an array element nor use
>
> s/assigned-to/assigned to/

I did that on purpose to remove any ambiguity about what object "to" acts upon.
I've used s/assigned-to/so created/

> "incuding"

Thanks.

> > +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 `tt(nameref)'"?

Better, thank you.

> > +When both a named reference and the `tt((P))' flag appear, the named
> > +reference is resolved before `tt((P))' is applied.
>
> Add a test for this last sentence?

I can't think of a way to do so.  Given ${(P)ptr}, there are two possibilities:
1) ptr is a scalar, in which case we're not testing the right thing
2) ptr is a reference, so any other order of expansion is meaningless

If ptr is a reference, a working test of ${ptr} implies that ${(P)ptr}
also works.  I almost didn't include that sentence in the doc at all,
but I found the nameref sections of "man ksh93" to be so nearly
unreadable that I went as far as I could in the other direction.  (The
sections on discipline functions are even worse, even the author of
the O'Reilly ksh book basically gives up on the topic.)

> WDYT of documenting somewhere in the manual namerefs are new in 5.10?

I was going to add something to NEWS and README eventually ... also, I
wasn't sure we'd landed on a version number yet.  I suppose (once we
do) a mention wouldn't hurt since the docs are likely to end up on
line.

> > +em(This is a misfeature.)
>
> Does "This is a misfeature" mean "This may change in the future to be
> compatible with ksh93"?

Oops, I was supposed to delete that whole paragraph, I already fixed
that with the base/width overloading.

> >  texinode(Parameters Set By The Shell)(Parameters Used By The Shell)(Local Parameters)(Parameters)
> >  sect(Parameters Set By The Shell)
>
> s/Local Parameters/Named References/

Thanks, thought I'd caught all of those ... it was nice when the older
version of yodl complained about those incorrect references.

> (public service announcement: we have *.yo syntax highlighting for Vim
> in our tree)

I have a yodl-mode.el file for emacs floating around somewhere too,
tho it hasn't been updated since about GNU emacs 12.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/3] Documentation for named references
  2023-02-07  3:25   ` Bart Schaefer
@ 2023-02-07 10:51     ` Daniel Shahaf
  2023-02-07 16:53       ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Daniel Shahaf @ 2023-02-07 10:51 UTC (permalink / raw)
  To: Zsh hackers list

Bart Schaefer wrote on Mon, Feb 06, 2023 at 19:25:03 -0800:
> On Mon, Feb 6, 2023 at 4:57 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> >
> > Bart Schaefer wrote on Sun, Feb 05, 2023 at 18:26:50 -0800:
> 
> > > +tt(-n).  The var(name) assigned-to may not be an array element nor use
> >
> > s/assigned-to/assigned to/
> 
> I did that on purpose to remove any ambiguity about what object "to" acts upon.

I see.

> I've used s/assigned-to/so created/

+1

> > > +When both a named reference and the `tt((P))' flag appear, the named
> > > +reference is resolved before `tt((P))' is applied.
> >
> > Add a test for this last sentence?
> 
> I can't think of a way to do so.  Given ${(P)ptr}, there are two possibilities:
> 1) ptr is a scalar, in which case we're not testing the right thing
> 2) ptr is a reference, so any other order of expansion is meaningless
> 

I'm not sure I follow what would be "meaningless" here.  I guess you
mean that ${(P)foo} requires foo to be a scalar's name and expands to
a list of words, so trying to expand ${(P)} first to a list of words and
then treating that as a nameref wouldn't be implementable.  Is that
what you mean?

Anyway, would it be worthwhile to add a few simple tests of the
combination of (P) and namerefs?  I have these:

 pointee=value
 typeset -n nr=pointee
 myscalar=nr
 echo ${(P)myscalar}
0:named references with (P), as ${(P)name_of_nameref}
*>value

 pointee=value
 myscalar=pointee
 typeset -n nr=myscalar
 echo ${(P)nr}
0:named references with (P), as ${(P)nameref}
*>value

(the asterisks are so MUAs don't treat the ">" as a quote)

> If ptr is a reference, a working test of ${ptr} implies that ${(P)ptr}
> also works. [...]

That doesn't seem to be the case in the following:

% ary=( 'bry[1]' 'bry[2]' )  
% bry=( lorem ipsum )
% typeset -n nr='ary[2]' 
% echo $nr
bry[2]
% echo ${(P)nr} 
zsh: bad substitution

I expected this to expand to "ipsum".

I also expected $nr and ${nr} to behave identically to each other, but:

% ary=( foo bar )
% typeset -n nr='ary[2]' 
% echo ${nr}
zsh: bad substitution
% echo $nr  
bar
% 

>


> > WDYT of documenting somewhere in the manual namerefs are new in 5.10?
> 
> I was going to add something to NEWS and README eventually ... also, I
> wasn't sure we'd landed on a version number yet.  I suppose (once we
> do) a mention wouldn't hurt since the docs are likely to end up on
> line.

That's one argument, yes.  Furthermore, I think stating version numbers
would be useful even in the locally-installed versions of the manual,
since someone might run a bleeding edge distro and write code that
targets LTS distros.

> > >  texinode(Parameters Set By The Shell)(Parameters Used By The Shell)(Local Parameters)(Parameters)
> > >  sect(Parameters Set By The Shell)
> >
> > s/Local Parameters/Named References/
> 
> Thanks, thought I'd caught all of those ... it was nice when the older
> version of yodl complained about those incorrect references.

The yodl macro is a thin wrapper around the texinfo macro.  Perhaps
texinfo warns about this somewhere in its output?


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/3] Documentation for named references
  2023-02-07 10:51     ` Daniel Shahaf
@ 2023-02-07 16:53       ` Bart Schaefer
  2023-02-08 21:28         ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2023-02-07 16:53 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: Zsh hackers list

On Tue, Feb 7, 2023 at 2:52 AM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> Bart Schaefer wrote on Mon, Feb 06, 2023 at 19:25:03 -0800:
> > On Mon, Feb 6, 2023 at 4:57 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> > >
> > > Bart Schaefer wrote on Sun, Feb 05, 2023 at 18:26:50 -0800:
> >
> > > > +When both a named reference and the `tt((P))' flag appear, the named
> > > > +reference is resolved before `tt((P))' is applied.
> > >
> > > Add a test for this last sentence?
> >
> > I can't think of a way to do so.  Given ${(P)ptr}, there are two possibilities:
> > 1) ptr is a scalar, in which case we're not testing the right thing
> > 2) ptr is a reference, so any other order of expansion is meaningless
> >
>
> I'm not sure I follow what would be "meaningless" here.

${(P)name} is defined to expand $name and then treat the string value
as a further parameter name.  What would it mean to expand a named
reference without resolving it?  Just ignore that it's a named
reference and treat it as a scalar?

(Skipping suggested test cases, I'll add them just for completeness)

> > If ptr is a reference, a working test of ${ptr} implies that ${(P)ptr}
> > also works. [...]
>
> That doesn't seem to be the case in the following:
>
> % ary=( 'bry[1]' 'bry[2]' )
> % bry=( lorem ipsum )
> % typeset -n nr='ary[2]'
> % echo $nr
> bry[2]
> % echo ${(P)nr}
> zsh: bad substitution

That doesn't have to do specifically with (P), it's the same error as this:

> % ary=( foo bar )
> % typeset -n nr='ary[2]'
> % echo ${nr}
> zsh: bad substitution

That'll have to be looked at.

> > > s/Local Parameters/Named References/
> >
> > Thanks, thought I'd caught all of those ... it was nice when the older
> > version of yodl complained about those incorrect references.
>
> The yodl macro is a thin wrapper around the texinfo macro.  Perhaps
> texinfo warns about this somewhere in its output?

I'm grumbling about the wrong thing, it's actually "makeinfo" that
used to complain but doesn't in newer versions of texinfo.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/3] Documentation for named references
  2023-02-07 16:53       ` Bart Schaefer
@ 2023-02-08 21:28         ` Bart Schaefer
  0 siblings, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 2023-02-08 21:28 UTC (permalink / raw)
  To: Zsh hackers list

On Tue, Feb 7, 2023 at 8:53 AM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> ${(P)name} is defined to expand $name and then treat the string value
> as a further parameter name.  What would it mean to expand a named
> reference without resolving it?  Just ignore that it's a named
> reference and treat it as a scalar?

That last is in fact what bash does with ${!name} (when not a nameref,
it's like ${(P)name}.  I suppose it would be nice to have a way to
expand the name to which a named reference points, but I'm not sure
overloading (P) is the best way.

There's a slew of other special bash meanings of parameter references
that start with "!":
  ${!name*} == ${(k)parameters[(I)name*]}
  ${!name@} == ${(@k)parameters[(I)name*]}
  ${!name[*]} == ${(k)name} (but indexes of ordinary arrays, too)
  ${!name[@]} == ${(@k)name} (ditto)

Indexes of ordinary arrays aren't very useful in zsh because arrays
are not sparse, every element is at least empty string, but you can
get the indexes of all non-empty elements with
  ${(*)name//(#m)?*/${name[(ie)$MATCH]}}


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-02-08 21:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-06  2:26 [PATCH 3/3] Documentation for named references Bart Schaefer
2023-02-07  0:56 ` Daniel Shahaf
2023-02-07  3:25   ` Bart Schaefer
2023-02-07 10:51     ` Daniel Shahaf
2023-02-07 16:53       ` Bart Schaefer
2023-02-08 21:28         ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).