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=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 7779 invoked from network); 9 Feb 2023 00:47:27 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 9 Feb 2023 00:47:27 -0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Message-ID:Date:Content-ID: Content-Type:MIME-Version:Subject:To:References:From:In-reply-to:cc:Reply-To: Content-Transfer-Encoding:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=9PPNWniwnNwg7S3tZxpcDtG7t3l+sVviB/HBL8YO8ag=; b=PZ2Lv2E165hAjMMMFERbTqGZsv 2eCSDdeU7i4aRM0NPxzCXH/g354X1Afk74viCNrtY48e99LD6v4+Mf5hg/KR7FATGusb9Pxxg9AWc qwnaLlxmytM/BUbPHSeO3Nc9BdB5bariPI9QIpKhLoOiGJk9K6yJLi2nhuVCHCxBOCsuDx2BY1R/4 dZtnG+NBifhn/HD6JtY77lLExUuRdYITsbC4f0/4LE6dvxKEy46V6cjJJHlIX38FBmTAnO3pIzpoo V6H/ehDUIHXLSlzIRWbwHWcQAjX3Lsq3ZkG8c9fv6zQCkaTVzMCBMHUxred8VJVRB9HMH9jEv1i6a d34+PFSw==; Received: by zero.zsh.org with local id 1pPv5s-0005Wg-Pq; Thu, 09 Feb 2023 00:47:20 +0000 Received: by zero.zsh.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) id 1pPv5b-0005DC-Ei; Thu, 09 Feb 2023 00:47:03 +0000 Received: from [192.168.178.21] (helo=hydra) by mail.kiddle.eu with esmtp(Exim 4.95) (envelope-from ) id 1pPv5a-0003HN-Pw; Thu, 09 Feb 2023 01:47:03 +0100 cc: Zsh hackers list In-reply-to: From: Oliver Kiddle References: <67689-1675827940.088548@BxvG.D9_b.7RzI> To: Bart Schaefer Subject: Re: [PATCH 1/3]: Add named references MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <12607.1675903622.1@hydra> Date: Thu, 09 Feb 2023 01:47:02 +0100 Message-ID: <12608-1675903622.800470@Xj82.e3y1.svhG> X-Seq: 51385 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: Bart Schaefer wrote: > > One ksh feature which this doesn't cover is the special behaviour in ksh > > that `typeset -n ref=$1` will use the calling function scope to resolve > > the target. > > This should also work after patch 4/3. > > % typeset outside=OUTSIDE > % () { > typeset -n ref=$1 > print $ref > } outside > OUTSIDE > > Or do I misunderstand? In ksh you could pass "ref" as a parameter and the nameref would provide access to the outside variable despite the name clash. > > The positional parameters are special-cased which I > > find rather ugly. > > There's nothing explaining this in "man ksh93", can you point me > somewhere? Not that your description makes this sound particular > attractive. The manual does seem rather vague on this. I've long been aware of it so the detail may have come to me via the old ast-ksh lists. But to demonstrate: % function f { > typeset out=99 var=$1 > nameref ref1=$1 > nameref ref2=$var > echo f: $ref1 $ref2 > ref1=1 > ref2=2 > } % out=0 % f out f: 0 99 % echo $out 1 So $1 as the target of a nameref is special. I don't especially like this. Everywhere else in the shell, a variable reference like $1 is no different from using the text it would expand to explicitly. I don't think we need to worry about the level of ksh93 compatibility here because our default dynamic scoping mean a ksh script will work if variable names don't clash. > > You could overload -u or -U for indicating Tcl-like > > uplevel. > > It'd be easier to overload "-i N" for this since it already populates > the "base" integer in Param. Not with the right number, though. Tcl's uplevel gives a distance (up the procedure calling stack) to move. 1 being the default. You can prefix with # to get an absolute level but that doesn't seem especially useful. So 1 would mean $((locallevel-1)) in absolute terms. Note that Tcl's uplevel is like a precommand modifier in zsh terms so is not limited to defining references. However I still prefer the other solution I mentioned with \&. > I'm still not entirely following what problem this solves. It solves the problem of name clashes between a function and the calling function. Consider Completion/Base/Utility/_call_function, It expects the name of a parameter in $1. It does: local _name _ret _name="$1" ... _ret=... eval "${_name}=${_ret}" The underscores are there largely to avoid name clashes. In ksh, this could instead be: nameref ret="$1" ret=... And it wouldn't matter if ret is also the variable name in the calling function. > > I think a better solution is to take some syntax that isn't a valid > > variable name. e.g typeset -n ref=\&1 Repeated use of an initial & would > > indicate where another level of scope should be ascended. Wrapper > > functions then don't need their own nameref and can just pass, e.g. > > \&var as the variable parameter. > > You're going to have to write out an example, sorry. With this idea: typeset -n ret=\&1 would be like ksh's: typeset -n ret=$1 But you could also do typeset -n ret=\&var The code would strip the initial \&, go up one local level and see what $var is in that scope. If the result also starts with an &, it would repeat the process going up a further level. So a wrapper function to, e.g. _call_function could pass "&$1" directly as the first parameter instead of needing a local nameref of it's own. You could optionally allow "&&var" to go up two levels. It doesn't need to be & if you think a different character is better, it just needs to not be a valid variable name. Does that make any more sense than the previous explanation? > I'm also thinking about that. The only use-case would be to prevent > something from doing "typeset +n ref". Also prevents typeset -n ref=othervar It is just as useful or useless as -r with other variables. > > > With respect to zsh/param/private parameters, it's presently > > > prohibited to have a "public" reference to a private parameter. It > > > might be possible to change this if someone can think of a use case. > > > > To a user it would seem like a fairly arbitrary restriction. > > What purpose does it serve? How does it help to have two names for > the same thing, one of which is "hidden" and the other isn't? The > only analogy I can think of would be having a writable name for a > read-only variable. If two functions are developed independently, they shouldn't need to worry about the possibility of using the same variable name for different purposes. This is the main benefit of private in general. An old function like _call_function (updated to use nameref but still using local) could be used by someone writing a new function where they pass a private variable as the first parameter. If they are treating _call_function as a black box, how are they to know that private variables are not valid for the passed $1. It'd be an arbitrary limitation. > The special behavior of namerefs in "for" loops and implementing > "unset -n" might be good; the latter isn't mentioned until the "unset" > builtin in the ksh93 doc so I missed it entirely. Given that you implemented references to array members, being able to iterate over array elements with for could be nice. Perhaps something like: for ref in 'arr[*]'; do maybe [@] to include empty elements. On the subject references to array elements, it does seem both powerful and dangerous that subscripts are evaluated on reference. The subscript should perhaps be evaluated with the same local level as the array itself. And it could be wise to limit what can be done as part of the subscript evaluation to avoid a CVE similar to the last one. > > I think I also concluded that it > > wouldn't work for private variables because of their somewhat too clever > > implementation. > > They could be a lot less clever if they could move into the main > shell. Most of the cleverness was necessary for making them modular. I would favour moving them to the main shell. And then making extensive use of them in completon etc. There are things that could move in the opposite direction if we want to reduce bloat. Mail checking for example. Oliver