help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Oliver Kiddle <opk@zsh.org>
Cc: Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: [PATCH 1/3]: Add named references
Date: Fri, 10 Feb 2023 23:45:36 -0800	[thread overview]
Message-ID: <CAH+w=7aKwKhdXjPo2FQG1GqjHQzX=5to_m6kZeL-UFfQh_XMtw@mail.gmail.com> (raw)
In-Reply-To: <40726-1676098925.110777@U2kb.d0Pd.I9ml>

On Fri, Feb 10, 2023 at 11:02 PM Oliver Kiddle <opk@zsh.org> wrote:
> Bart Schaefer wrote:
> > On Thu, Feb 9, 2023 at 3:07 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
> > >
> > > > Ksh prints "global reference cannot refer to local variable".
> I'd make it a fatal error unconditionally. I don't like it if the target
> of a nameref can switch to something else following a return.

Making it an unconditional error means that this sort of thing doesn't work:

typeset -n ref
() {
  typeset a=A b=B c=C
  for ref in a b c; do ref=${(L)ref}; done

> I'd be
> fine with the reference becoming unset at the time of the return if it
> refers to a variable that is going out of scope. Can that be done as
> part of the same code that drops the local variables?

Maybe.  Might look at that tomorrow.

> The mention of WARN_NESTED_VAR raises something else. Surely a reference
> should disable that warning:

Actually there's an argument that an unexpected up-reference is a
really good reason for that warning.  A function that intentionally
uses an up-reference could turn the option off locally.

> > > Relatedly, what should happen on any failed assignment?
> Current code even allows:
>   typeset -n ref
>   ref=ref

That's fixed in my sandbox.  Patch eventually forthcoming.

> I'd suggest that we need the self-reference check whenever assigning to
> a reference. But that entails evaluation of a subscript.

As I have it right now, self-reference checks do happen at any
assignment.  That's why I wonder if deleting the offending parameter
is OK.

Circular references hidden inside subscripts end up expanding to empty
string, as do command substitutions with the NO_EXEC trick.

> Do we to put recommended good practices in the doc at all as opposed to
> it being a terse description of the functionality. I'd prefer it out of
> the way with examples rather than adding fluff to the places you list.

The Functions chapter was rather too terse.  Here's what I've written to add:

--- 8< ---
Parameters declared by any of the 'typeset' family of commands during
the execution of a function become _local_ to the function unless the
'-g' option is used.  This is the _scope_ of the parameter, which
extends dynamically to any other functions called by the declaring
function.  In most cases, local parameters take the place of any other
parameter having the same name that was assigned or declared in an
earlier function scope.  (See *note Local Parameters::.)

A named parameter declared with the '-n' option to any of the 'typeset'
commands becomes a reference to a parameter in scope at the time of
assignment to the named reference, which may be at a different call
level than the declaring function.  For this reason, it is good practice
to declare a named reference as soon as the referent parameter is in
scope, and as early as possible in the function if the reference is to a
parameter in a calling scope.

A typical use of named references is to pass the name of the referent
as a positional parameter.  For example,

     pop() {
       local -n ref=$1
       local last=$ref[$#ref]
       print -r -- $last
     array=( a list of five values )
     pop array

prints the word values and shortens $array to '( a list of five )'.
There are no local parameters in pop at the time 'ref=$1' is assigned,
so 'ref' becomes a reference to 'array' in the caller.
--- >8 ---

> I'd also consider it bad practice not to always assign a reference when
> creating it.

That also doesn't work with the for-loop example above (even if the
nameref is moved inside the function).

  reply	other threads:[~2023-02-11  7:46 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-06  2:21 Bart Schaefer
2023-02-08  3:45 ` Oliver Kiddle
2023-02-08  4:59   ` Bart Schaefer
2023-02-08 23:16     ` Bart Schaefer
2023-02-09  0:47     ` Oliver Kiddle
2023-02-09  2:01       ` Oliver Kiddle
2023-02-09  5:45         ` Bart Schaefer
2023-02-09  4:49       ` Bart Schaefer
2023-02-09 20:49         ` Oliver Kiddle
2023-02-09 23:07           ` Bart Schaefer
2023-02-11  3:04             ` Bart Schaefer
2023-02-11  3:55               ` Bart Schaefer
2023-02-11  5:36                 ` Speaking of dangerous referents Bart Schaefer
2023-02-12  8:00                   ` Oliver Kiddle
2023-02-12  8:34                     ` Bart Schaefer
2023-02-11  7:02               ` [PATCH 1/3]: Add named references Oliver Kiddle
2023-02-11  7:45                 ` Bart Schaefer [this message]
2023-02-11 23:43                   ` Bart Schaefer
2023-02-11 23:45                     ` Bart Schaefer
2023-02-12  7:38                     ` Oliver Kiddle
2023-02-12  9:02             ` Oliver Kiddle
2023-02-12 18:59               ` Bart Schaefer
2023-02-12 19:45                 ` PM_* flags in zsh.h (was Re: [PATCH 1/3]: Add named references) Bart Schaefer
2023-02-12 21:01                   ` Oliver Kiddle
2023-02-12 22:54                 ` [PATCH 1/3]: Add named references Oliver Kiddle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAH+w=7aKwKhdXjPo2FQG1GqjHQzX=5to_m6kZeL-UFfQh_XMtw@mail.gmail.com' \
    --to=schaefer@brasslantern.com \
    --cc=opk@zsh.org \
    --cc=zsh-workers@zsh.org \


* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox


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