zsh-workers
 help / color / mirror / code / Atom feed
From: "Bart Schaefer" <schaefer@brasslantern.com>
To: zsh-workers@math.gatech.edu
Subject: PATCH: 3.1.5-pws-3: Associative arrays and ${...:=...}
Date: Mon, 14 Dec 1998 22:56:35 -0800	[thread overview]
Message-ID: <981214225636.ZM4182@candle.brasslantern.com> (raw)

This patch permits associative arrays to be created or assigned-to using
the := and ::= parameter substitution syntax.  This is more convenient than
having to use `typeset -A name` before any other references to an AA.  The
syntax is simply to double the `A' substitution flag, like so:

zsh% echo ${(AA)=assoc::=key1 value1 key2 value2}
value2 value1

Note that, as usual for AAs, only the values are substituted, and they may
not be substituted in the same order that they were assigned.

The reason for the = between (AA) and assoc is to turn on shwordsplit.  If
this is not done, "key1 value1 key2 value2" is taken as a single string,
and the assignment fails.  You can also cause splitting in other ways; e.g.
this copies the entire command hash table into the parameter `commands':

zsh% : ${(AAs:=:)commands::=${(j:=:)$(hash -f;hash)}}

(I suspect something like that could be extremely useful when programming
completions.)

There are two quirks that should be mentioned.  The first is that you
can't presently assign to a subscripted AA element this way; e.g. this
works for arrays (always did, my patch has nothing to do with it):

zsh% : ${(A)array[2]::=two}

But this fails for AAs:

zsh% : ${(AA)assoc[two]::=2}
zsh: attempt to set slice of associative array

I now believe I know how to fix this, but I hadn't figured it out yet
when I fixed up sethparam() a few patches ago.

The second quirk is that ${(A)name::=...} (note, only one `A') doesn't
convert associations into ordinary arrays.  If $name exists and is an
AA, it's assigned to as an AA, just as happens with regular name=(...)
assignment syntax.

zsh% echo ${(A)bar:=x}
x
zsh% echo ${(AA)=foo::=one 1 two 2}
2 1
zsh% echo ${(A)foo:=x}
zsh: bad set of key/value pairs for associative array

This patch also makes use of the SCANPM flags in paramsubst(), now that
they're available outside of params.c.

Index: Src/subst.c
===================================================================
--- subst.c	1998/12/13 23:40:57	1.6
+++ subst.c	1998/12/14 09:17:38
@@ -720,8 +720,8 @@
     int eval = 0;
     int nojoin = 0;
     char inbrace = 0;		/* != 0 means ${...}, otherwise $... */
-    char hkeys = 0;		/* 1 means get keys from associative array */
-    char hvals = 0;		/* > hkeys get values of associative array */
+    char hkeys = 0;
+    char hvals = 0;
 
     *s++ = '\0';
     if (!ialnum(*s) && *s != '#' && *s != Pound && *s != '-' &&
@@ -739,7 +739,7 @@
 	inbrace = 1;
 	s++;
 	if (*s == '!' && s[1] != Outbrace && emulation == EMULATE_KSH) {
-	    hkeys = 1;
+	    hkeys = SCANPM_WANTKEYS;
 	    s++;
 	} else if (*s == '(' || *s == Inpar) {
 	    char *t, sav;
@@ -762,7 +762,7 @@
 		case Outpar:
 		    break;
 		case 'A':
-		    arrasg = 1;
+		    ++arrasg;
 		    break;
 		case '@':
 		    nojoin = 1;
@@ -897,10 +897,10 @@
 		    break;
 
 		case 'k':
-		    hkeys = 1;
+		    hkeys = SCANPM_WANTKEYS;
 		    break;
 		case 'v':
-		    hvals = 2;
+		    hvals = SCANPM_WANTVALS;
 		    break;
 
 		default:
@@ -979,9 +979,8 @@
 	*s = sav;
 	v = (Value) NULL;
     } else {
-	/* 2 == SCANPM_WANTKEYS, 1 == SCANPM_WANTVALS, see params.c */
 	if (!(v = fetchvalue(&s, (unset(KSHARRAYS) || inbrace) ? 1 : -1,
-			     (hkeys ? 2 : 0) + ((hvals > hkeys) ? 1 : 0))))
+			     hkeys|hvals)))
 	    vunset = 1;
     }
     while (v || ((inbrace || (unset(KSHARRAYS) && vunset)) && isbrack(*s))) {
@@ -1260,7 +1259,12 @@
 			*p++ = ztrdup(*t++);
 		    }
 		    *p++ = NULL;
-		    setaparam(idbeg, a);
+		    if (arrasg > 1) {
+			Param pm = sethparam(idbeg, a);
+			if (pm)
+			    aval = paramvalarr(pm->gets.hfn(pm), hkeys|hvals);
+		    } else
+			setaparam(idbeg, a);
 		} else {
 		    untokenize(val);
 		    setsparam(idbeg, ztrdup(val));

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


                 reply	other threads:[~1998-12-15  6:58 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=981214225636.ZM4182@candle.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@math.gatech.edu \
    /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).