From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.4 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,RDNS_NONE,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: from authenticated user by zero.zsh.org with local id 1kiAUg-0008vZ-8I; Thu, 26 Nov 2020 06:11:02 +0000 Authentication-Results: zsh.org; iprev=pass (relay12.mail.gandi.net) smtp.remote-ip=217.70.178.232; dmarc=none header.from=chazelas.org; arc=none Received: from relay12.mail.gandi.net ([217.70.178.232]:34717) by zero.zsh.org with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) id 1kiAUC-0008fz-Qp; Thu, 26 Nov 2020 06:10:33 +0000 Received: from chazelas.org (unknown [94.10.124.211]) (Authenticated sender: stephane@chazelas.org) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 920A1200002; Thu, 26 Nov 2020 06:10:30 +0000 (UTC) Date: Thu, 26 Nov 2020 06:10:29 +0000 From: Stephane Chazelas To: Felipe Contreras Cc: Bart Schaefer , Zsh hackers list Subject: Re: More rabbit-holes with unset variables Message-ID: <20201126061029.in5tpnrg5bplam5k@chazelas.org> Mail-Followup-To: Felipe Contreras , Bart Schaefer , Zsh hackers list References: <20201125131921.vay7h3xk5qn4odgg@chazelas.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: X-Seq: 47631 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: Archived-At: 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