zsh-workers
 help / color / mirror / code / Atom feed
From: Stephane Chazelas <stephane@chazelas.org>
To: Felipe Contreras <felipe.contreras@gmail.com>
Cc: Bart Schaefer <schaefer@brasslantern.com>,
	Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: More rabbit-holes with unset variables
Date: Thu, 26 Nov 2020 06:10:29 +0000	[thread overview]
Message-ID: <20201126061029.in5tpnrg5bplam5k@chazelas.org> (raw)
In-Reply-To: <CAMP44s0-ki=TBzTwnqx10FcTLX4mbphwN88UCx0+h97JTecBWA@mail.gmail.com>

2020-11-25 16:17:46 -0600, Felipe Contreras:
[...]
>   The variable whose name is specified shall be created as a local
> variable with name "name". It
>   shall inherit its initial value, as well as the exported and
> readonly flags, from the variable
>   with the same name in the surrounding dynamic scope if there is one;
> otherwise, the variable is
>   initially unset. Then, if "=word" is provided, the value of that
> local variable shall then be set
>   to word.
[...]

You'd describing the ash/bosh behaviour. Most other shells
behave differently. As mentioned at that SE Q&A or in that POSIX
issue, there is a strong case for that variable to be a brand
new variable with an initial unset or empty/0/empty-list value
depending on the type.

In reality, depending on the shell you get:

- variable left as is from the parent scope (inherit, value,
  type, attributes), but restored upon return of function.
  Useful in things like "local PATH" where you want to keep the
  current value of PATH, be able to do modifications and restore
  the original value upon return of the function.

  That approach is not acceptable for a shell with other types
  of variables (array, hash, compound) and with variable
  attributes (integer, float, padding, uppercase...). Because
  that would invalidate all the uses like:

  f() { local i; for i do ...; done; }

  Which would be broken if i remained a hash/integer/padded...

  In ash, that function doesn't work in contexts where i has
  been made read-only in a parent scope, and leaks the value of
  i to executed commands if it was exported. NetBSD sh added
  "local -N i" for that. Though you could also do
  "local var; unset var" (not portable as it doesn't work in
  mksh/yash)

- variable created unset but inheriting some of the attributes
  (bash) that's the worst of both world as you don't know what
  you're going to get. (localvar_unset doesn't address that).

- variable created anew initially unset

- variable created anew with initial value (zsh).

As to unset vs initial value, both have merits. While I'd tend
to prefer "initially unset", it makes sense that "local -i i;
echo "$i"" outputs an integer. Or that "local -Z2 v; echo $#v"
outputs 2.

In any case, I don't think zsh can change its default behaviour
as it would break backward compatibility.

It could add -N/-I à la NetBSD sh if people found it was useful
enough.

It could try and emulate ksh in ksh emulation, but which ksh?
ksh88, ksh93 and mksh behave radically differently in that
regard. Also few people use ksh these days, so I'm not sure it's
worth the effort. While the ksh emulation mode can help with
bash compatibility, bash's behaviour in this instent is also
very different.

-- 
Stephane



  reply	other threads:[~2020-11-26  6:11 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-25  7:02 Bart Schaefer
2020-11-25 13:19 ` Stephane Chazelas
2020-11-25 22:17   ` Felipe Contreras
2020-11-26  6:10     ` Stephane Chazelas [this message]
2020-11-26  7:20       ` Felipe Contreras
2020-11-26 11:21         ` Oliver Kiddle
2020-11-26 11:29           ` Roman Perepelitsa
2020-11-26 19:08             ` Felipe Contreras
2020-11-26 19:29           ` Felipe Contreras
2020-11-26 21:13           ` Bart Schaefer
2020-11-26 21:31             ` Felipe Contreras
2020-11-26 23:29               ` Bart Schaefer
2020-11-26 23:32                 ` Bart Schaefer
2020-11-26 23:53                 ` Felipe Contreras
2020-11-27  0:23                   ` Bart Schaefer
2020-11-27  1:51                     ` Felipe Contreras
2020-11-27 20:01                       ` Bart Schaefer
2020-11-27 21:49                         ` Felipe Contreras
2020-11-27 22:06                           ` Bart Schaefer
2020-11-27 23:35                             ` Felipe Contreras
2020-11-26 22:07       ` Bart Schaefer
2020-11-26 20:41     ` Bart Schaefer
2020-11-26 20:49       ` Stephane Chazelas
2020-11-26 21:20       ` Felipe Contreras
2020-11-26 22:41         ` Bart Schaefer
2020-11-26 23:45           ` Felipe Contreras
2020-11-27  0:09             ` Bart Schaefer
2020-11-27  0:30               ` Felipe Contreras
2020-11-27  0:51                 ` Bart Schaefer
2020-11-27  1:30                   ` Felipe Contreras
2020-11-27 20:54                     ` Bart Schaefer
2020-11-27 22:10                       ` Felipe Contreras
2020-11-27 22:39                         ` Bart Schaefer
2020-11-28  0:00                           ` Felipe Contreras
2020-11-28  0:04                             ` Bart Schaefer
2020-11-28 10:52                               ` Felipe Contreras
2020-11-28  0:36                             ` The emulation rabbit-hole RE typeset/unset Bart Schaefer
2020-11-28 11:35                               ` Felipe Contreras
2020-11-28 16:56                                 ` Bart Schaefer
2020-12-01  8:49                                   ` Felipe Contreras

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:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

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

  git send-email \
    --in-reply-to=20201126061029.in5tpnrg5bplam5k@chazelas.org \
    --to=stephane@chazelas.org \
    --cc=felipe.contreras@gmail.com \
    --cc=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* 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

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