zsh-workers
 help / color / mirror / code / Atom feed
* Re:  Associative array ordering and selective unset (Re: Example function)
@ 1999-02-02 16:58 Sven Wischnowsky
  1999-02-02 17:41 ` ${(P)${foo}} (Re: Associative array ordering) Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Sven Wischnowsky @ 1999-02-02 16:58 UTC (permalink / raw)
  To: zsh-workers


I wrote:

> Maybe yet another flag? E.g.: `P' makes the thing after the
> flags be used as the name of a parameter. So `${(P)foo}' is the same
> as `$foo', but `${(P)${foo}}' will take the value of `foo' as the name 
> of a parameter and work on it. So your example would become:
> 
>   if [[ $#arg > 1 && ${(Pt)${argv[1]}} == association ]] ...

The patch below does this (it was quite easy). With it you can do
things like the above or `${(P)+${foo}}' to see if the parameter whose 
name is stored in `foo' is set. If the inner `${...}' produces
multiple words they are joind using IFS which will result in an
invalid parameter name (which is reported as being unset). Maybe we
should make the code test if it is a valid name and barf otherwise. Or 
we could use only the first word. Any other suggestions?

But I don't know if you like this anyway...

The patch also changes the docs and the new-completion-examples.

Bye
 Sven

--- os/subst.c	Mon Feb  1 10:53:56 1999
+++ Src/subst.c	Tue Feb  2 17:27:50 1999
@@ -718,10 +718,12 @@
     int copied = 0;
     int arrasg = 0;
     int eval = 0;
+    int aspar = 0;
     int nojoin = 0;
     char inbrace = 0;		/* != 0 means ${...}, otherwise $... */
     char hkeys = 0;
     char hvals = 0;
+    int subexp;
 
     *s++ = '\0';
     if (!ialnum(*s) && *s != '#' && *s != Pound && *s != '-' &&
@@ -813,6 +815,9 @@
 		case 'e':
 		    eval = 1;
 		    break;
+		case 'P':
+		    aspar = 1;
+		    break;
 
 		case 'c':
 		    whichlen = 1;
@@ -949,7 +954,8 @@
 	    } else
 		globsubst = 1;
 	} else if (*s == '+') {
-	    if (iident(s[1]))
+	    if (iident(s[1]) || (aspar && isstring(s[1]) &&
+				 (s[2] == Inbrace || s[2] == Inpar)))
 		chkset = 1, s++;
 	    else if (!inbrace) {
 		*aptr = '$';
@@ -965,7 +971,8 @@
     globsubst = globsubst && !qt;
 
     idbeg = s;
-    if (s[-1] && isstring(*s) && (s[1] == Inbrace || s[1] == Inpar)) {
+    if ((subexp = (s[-1] && isstring(*s) &&
+		   (s[1] == Inbrace || s[1] == Inpar)))) {
 	int sav;
 	int quoted = *s == Qstring;
 
@@ -973,17 +980,22 @@
 	skipparens(*s, *s == Inpar ? Outpar : Outbrace, &s);
 	sav = *s;
 	*s = 0;
-	if (multsub(&val, &aval, &isarr, NULL) && quoted) {
+	if (multsub(&val, (aspar ? NULL : &aval), &isarr, NULL) && quoted) {
 	    isarr = -1;
 	    aval = alloc(sizeof(char *));
-	}
+	    aspar = 0;
+	} else if (aspar)
+	    idbeg = val;
 	if (isarr)
 	    isarr = -1;
 	copied = 1;
 	*s = sav;
 	v = (Value) NULL;
-    } else {
-	if (!(v = fetchvalue(&s, (wantt ? -1 :
+    }
+    if (!subexp || aspar) {
+	char *ov = val;
+
+	if (!(v = fetchvalue((subexp ? &ov : &s), (wantt ? -1 :
 				  ((unset(KSHARRAYS) || inbrace) ? 1 : -1)),
 			     hkeys|hvals)))
 	    vunset = 1;
--- od/Zsh/expn.yo	Mon Feb  1 10:53:36 1999
+++ Doc/Zsh/expn.yo	Tue Feb  2 17:51:35 1999
@@ -477,9 +477,10 @@
 pindex(GLOB_SUBST)
 Turn on the tt(GLOB_SUBST) option for the evaluation of
 var(spec); if the `tt(~)' is doubled, turn it off.  When this option is
-set, any pattern characters resulting
-from parameter expansion are eligible for filename expansion and filename
-generation.
+set, the string resulting from the expansion will be interpreted as a
+pattern thus becoming eligible for filename expansion and filename
+generation and usable as a pattern in pattern-matching contexts like
+the `tt(=)' and `tt(!=)' operators in conditions.
 )
 enditem()
 
@@ -522,6 +523,15 @@
 Perform em(parameter expansion), em(command substitution) and
 em(arithmetic expansion) on the result. Such expansions can be
 nested but too deep recursion may have unpredictable effects.
+)
+item(tt(P))(
+If used with a parameter name, this flag has no effect. But if it is
+used with a tt(${)...tt(}) type parameter expression or a
+tt($LPAR())...tt(RPAR()) type command substitution in place of
+the parameter name this flag makes the result of the expansion be
+taken as a parameter name which is then used. E.g. if you have
+`tt(foo=bar)' and `tt(bar=baz)', the string `tt(${(P)${foo}})' will be 
+expanded to `tt(baz)'.
 )
 item(tt(o))(
 Sort the resulting words in ascending order.
diff -u om/new-completion-examples Misc/new-completion-examples
--- om/new-completion-examples	Mon Feb  1 10:53:27 1999
+++ Misc/new-completion-examples	Tue Feb  2 17:43:34 1999
@@ -75,11 +75,8 @@
 # the arguments from the command line as its arguments.
 
 call-complete() {
-  local var
-
-  eval var\=\$\{\+$1\}
-  if (( var )); then
-    eval complist \$\{${1}\[\@\]\}
+  if [[ ${(P)+${1}} -eq 1 ]] then
+    complist ${(@P)${1}}
   else
     "$@"
   fi
@@ -96,15 +93,6 @@
   setopt localoptions nullglob rcexpandparam globdots
   unsetopt markdirs globsubst shwordsplit nounset
 
-  # We first try the `compctl's. This is without first (-T) and default (-D)
-  # completion. If you want them add `-T' and/or `-D' to this command.
-  # If this produces any matches, we don't try new style completion. If you
-  # want to have that tried anyway, remove the `[[ -nmatches ... ]] ...'
-  # below.
-
-  compcall
-  [[ -nmatches 0 ]] || return
-
   # An entry for `--first--' is the replacement for `compctl -T'
   # The `|| return 1' is used throughout: if a function producing matches
   # returns non-zero this is interpreted as `do not try to produce more matches'
@@ -117,6 +105,15 @@
   # convenience alias `compsub'.
 
   if [[ $CONTEXT == argument || $CONTEXT == command ]] then
+    # We first try the `compctl's. This is without first (-T) and default (-D)
+    # completion. If you want them add `-T' and/or `-D' to this command.
+    # If this produces any matches, we don't try new style completion. If you
+    # want to have that tried anyway, remove the `[[ -nmatches ... ]] ...'
+    # below.
+
+    compcall
+    [[ -nmatches 0 ]] || return
+
     compsub
   else
     # Let's see if we have a special completion definition for the other
@@ -205,7 +202,7 @@
     if [[ "$a[1]" = '(' ]] then
       ppres=( $a[2,-2]/ )
     else
-      eval ppres\=\( \$$a/ \)
+      ppres=( ${(P)${a}} )
       [[ $#ppres -eq 0 ]] && ppres=( $a/ )
     fi
     [[ $#ppres -eq 0 ]] && ppres=( '' )
@@ -329,11 +326,8 @@
 
 defcomp __subscr --subscr--
 __subscr() {
-  local t
-
-  eval t\=\$\{\(t\)$COMMAND\}
   compalso --math-- "$@"
-  [[ $t = assoc* ]] && eval complist -k \"\(\$\{\(k\)$COMMAND\}\)\"
+  [[ ${(Pt)${COMMAND}} = assoc* ]] && complist -k "( ${(kP)${COMMAND}} )"
 }
 
 # Do sub-completion for pre-command modifiers.

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 7+ messages in thread

* ${(P)${foo}} (Re: Associative array ordering)
  1999-02-02 16:58 Associative array ordering and selective unset (Re: Example function) Sven Wischnowsky
@ 1999-02-02 17:41 ` Bart Schaefer
  0 siblings, 0 replies; 7+ messages in thread
From: Bart Schaefer @ 1999-02-02 17:41 UTC (permalink / raw)
  To: zsh-workers

On Feb 2,  5:58pm, Sven Wischnowsky wrote:
} Subject: Re:  Associative array ordering and selective unset (Re: Example 
}
} I wrote:
} 
} > Maybe yet another flag? E.g.: `P' makes the thing after the
} > flags be used as the name of a parameter. So `${(P)foo}' is the same
} > as `$foo', but `${(P)${foo}}' will take the value of `foo' as the name 
} > of a parameter and work on it.
} 
} The patch below does this (it was quite easy).

Well, you got to that before I got around to responding to that particular
tidbit.

The other day someone asked about ksh namerefs in zsh, and I said that with
${(e)...} you didn't really need them.  Here's a case where they would have
been exactly what the doctor ordered; in an appropriate muddle of ksh and
zsh syntax,

	nameref ref=$arg[1]
	echo ${(t)!ref}

which is a whole lot easier on the eyes, it must be admitted.

} With it you can do
} things like the above or `${(P)+${foo}}' to see if the parameter whose 
} name is stored in `foo' is set.

There are actually several ways we can go from here.

We can keep Sven's syntax as is.

We can modify Sven's syntax so that ${(P)foo} is the same as ${(P)${foo}},
and make ${!foo} a synonym for it in ksh compatibility mode.  This is
almost like ksh namerefs except that they don't get their own namespace.

We can make ${!foo} a synonym for ${(P)${foo}} (either in ksh mode or all
the time), leaving ${(P)foo} alone.  I'm not too thrilled about this one.

We can add another hash table to be the nameref namespace, implement the
nameref and `typeset -n' builtins, and make ${(P)foo} [or another letter]
and ${!foo} synonyms where `foo' must be a nameref.  That would deprecate
${(P)${foo}}.

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ${(P)${foo}} (Re: Associative array ordering)
  1999-02-03 10:06 Sven Wischnowsky
@ 1999-02-03 10:42 ` Peter Stephenson
  0 siblings, 0 replies; 7+ messages in thread
From: Peter Stephenson @ 1999-02-03 10:42 UTC (permalink / raw)
  To: zsh-workers

Sven Wischnowsky wrote:
> I forgot to append the patch for the docs, sorry.

Needs a slight addition.

--- Doc/Zsh/expn.yo.par	Wed Feb  3 11:33:50 1999
+++ Doc/Zsh/expn.yo	Wed Feb  3 11:39:43 1999
@@ -531,7 +531,7 @@
 substitution in place of the parameter name this flag makes the result
 of the expansion be taken as a parameter name which is then
 used. E.g. if you have `tt(foo=bar)' and `tt(bar=baz)', the strings
-`tt(${(P)foo}' and `tt(${(P)${foo}})' will be expanded to `tt(baz)'.
+`tt(${(P)foo})' and `tt(${(P)${foo}})' will be expanded to `tt(baz)'.
 )
 item(tt(o))(
 Sort the resulting words in ascending order.

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ${(P)${foo}} (Re: Associative array ordering)
@ 1999-02-03 10:06 Sven Wischnowsky
  1999-02-03 10:42 ` Peter Stephenson
  0 siblings, 1 reply; 7+ messages in thread
From: Sven Wischnowsky @ 1999-02-03 10:06 UTC (permalink / raw)
  To: zsh-workers


I wrote:

> Bart Schaefer wrote:
> 
> > Let's go this way:  Implement ${(P)foo}, the same as ${(P)${foo}} where
> > the inner ${...} has no flags or modifiers, and leave ${!foo} undefined
> > until we do real namerefs (if we ever do).
> 
> Yep.

I forgot to append the patch for the docs, sorry.

Bye
 Sven

--- od/Zsh/expn.yo	Wed Feb  3 08:46:59 1999
+++ Doc/Zsh/expn.yo	Wed Feb  3 11:06:10 1999
@@ -525,13 +525,13 @@
 nested but too deep recursion may have unpredictable effects.
 )
 item(tt(P))(
-If used with a parameter name, this flag has no effect. But if it is
-used with a tt(${)...tt(}) type parameter expression or a
-tt($LPAR())...tt(RPAR()) type command substitution in place of
-the parameter name this flag makes the result of the expansion be
-taken as a parameter name which is then used. E.g. if you have
-`tt(foo=bar)' and `tt(bar=baz)', the string `tt(${(P)${foo}})' will be 
-expanded to `tt(baz)'.
+This makes the value of the parameter var(name) be taken as a
+parameter name on which to work. If it is used with a tt(${)...tt(})
+type parameter expression or a tt($LPAR())...tt(RPAR()) type command
+substitution in place of the parameter name this flag makes the result
+of the expansion be taken as a parameter name which is then
+used. E.g. if you have `tt(foo=bar)' and `tt(bar=baz)', the strings
+`tt(${(P)foo}' and `tt(${(P)${foo}})' will be expanded to `tt(baz)'.
 )
 item(tt(o))(
 Sort the resulting words in ascending order.

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ${(P)${foo}} (Re: Associative array ordering)
@ 1999-02-03  9:55 Sven Wischnowsky
  0 siblings, 0 replies; 7+ messages in thread
From: Sven Wischnowsky @ 1999-02-03  9:55 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> Let's go this way:  Implement ${(P)foo}, the same as ${(P)${foo}} where
> the inner ${...} has no flags or modifiers, and leave ${!foo} undefined
> until we do real namerefs (if we ever do).

Yep.

Bye
 Sven

--- os/subst.c	Wed Feb  3 10:55:01 1999
+++ Src/subst.c	Wed Feb  3 10:48:21 1999
@@ -991,6 +991,12 @@
 	copied = 1;
 	*s = sav;
 	v = (Value) NULL;
+    } else if (aspar) {
+	if ((v = getvalue(&s, 1))) {
+	    val = idbeg = getstrvalue(v);
+	    subexp = 1;
+	} else
+	    vunset = 1;
     }
     if (!subexp || aspar) {
 	char *ov = val;

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ${(P)${foo}} (Re: Associative array ordering)
  1999-02-03  8:02 Sven Wischnowsky
@ 1999-02-03  8:39 ` Bart Schaefer
  0 siblings, 0 replies; 7+ messages in thread
From: Bart Schaefer @ 1999-02-03  8:39 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers

On Feb 3,  9:02am, Sven Wischnowsky wrote:
} Subject: Re:  ${(P)${foo}} (Re: Associative array ordering)
}
} Bart Schaefer wrote:
} 
} > There are actually several ways we can go from here.
} > 
} > We can keep Sven's syntax as is.
} > 
} > We can modify Sven's syntax so that ${(P)foo} is the same as ${(P)${foo}},
} > and make ${!foo} a synonym for it in ksh compatibility mode.  This is
} > almost like ksh namerefs except that they don't get their own namespace.
} 
} I first thought about implementing ${(P)foo}, but implementing only the one 
} I did, seemed easier.

I suspect that's at least in part how we ended up with ${${param}} instead
of simply ${{param}} in the first place, but ....

} Now that I had a deeper look into the substitution 
} code again, making ${(P)foo} work doesn't look that complicated, too.
} Although that would be less powerful, so keeping the thing I
} implemented may still be useful.

Yes, particularly ${(P)$(...)} is probably useful, even if ${(P)${...}}
was not.

} Making ${!foo} a synonym may be useful, and as far as I can this we
} wouldn't have to restrict this to ksh compatibility mode (am I missing 
} something?).

You're missing `setopt banghist`, which is unsetopt in ksh mode.  ${!foo}
will have substituted the history item beginning with "foo" long before
it makes it to the parameter code.  That's why the ${!assoc[@]} syntax
is accepted only in ksh mode, too.

Let's go this way:  Implement ${(P)foo}, the same as ${(P)${foo}} where
the inner ${...} has no flags or modifiers, and leave ${!foo} undefined
until we do real namerefs (if we ever do).

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re:  ${(P)${foo}} (Re: Associative array ordering)
@ 1999-02-03  8:02 Sven Wischnowsky
  1999-02-03  8:39 ` Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Sven Wischnowsky @ 1999-02-03  8:02 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> On Feb 2,  5:58pm, Sven Wischnowsky wrote:
> } Subject: Re:  Associative array ordering and selective unset (Re: Example 
> }
> } I wrote:
> } 
> } > Maybe yet another flag? E.g.: `P' makes the thing after the
> } > flags be used as the name of a parameter. So `${(P)foo}' is the same
> } > as `$foo', but `${(P)${foo}}' will take the value of `foo' as the name 
> } > of a parameter and work on it.
> } 
> } The patch below does this (it was quite easy).
> 
> Well, you got to that before I got around to responding to that particular
> tidbit.
> 
> The other day someone asked about ksh namerefs in zsh, and I said that with
> ${(e)...} you didn't really need them.  Here's a case where they would have
> been exactly what the doctor ordered; in an appropriate muddle of ksh and
> zsh syntax,
> 
> 	nameref ref=$arg[1]
> 	echo ${(t)!ref}
> 
> which is a whole lot easier on the eyes, it must be admitted.

Yes, but in cases where you need it only once, this is a bit verbose,
don't you think?

> } With it you can do
> } things like the above or `${(P)+${foo}}' to see if the parameter whose 
> } name is stored in `foo' is set.
> 
> There are actually several ways we can go from here.
> 
> We can keep Sven's syntax as is.
> 
> We can modify Sven's syntax so that ${(P)foo} is the same as ${(P)${foo}},
> and make ${!foo} a synonym for it in ksh compatibility mode.  This is
> almost like ksh namerefs except that they don't get their own namespace.

I first thought about implementing ${(P)foo}, but implementing only the one 
I did, seemed easier. Now that I had a deeper look into the substitution 
code again, making ${(P)foo} work doesn't look that complicated, too.
Although that would be less powerful, so keeping the thing I
implemented may still be useful.
Making ${!foo} a synonym may be useful, and as far as I can this we
wouldn't have to restrict this to ksh compatibility mode (am I missing 
something?).

> We can make ${!foo} a synonym for ${(P)${foo}} (either in ksh mode or all
> the time), leaving ${(P)foo} alone.  I'm not too thrilled about this one.

Neither am I.

> We can add another hash table to be the nameref namespace, implement the
> nameref and `typeset -n' builtins, and make ${(P)foo} [or another letter]
> and ${!foo} synonyms where `foo' must be a nameref.  That would deprecate
> ${(P)${foo}}.

Namerefs may be useful anyway. But, as I said above I wouldn't like to
have to invent a nameref just to use this double-lookup once.

So, I'd vote for the ${!foo}=${(P)foo}=${(P)${foo}}-but-${(P)${foo#*=}}-
still-works suggestion, or for the last one (without the deprecation
bit). Those two can be combined anyway.

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~1999-02-03 10:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-02-02 16:58 Associative array ordering and selective unset (Re: Example function) Sven Wischnowsky
1999-02-02 17:41 ` ${(P)${foo}} (Re: Associative array ordering) Bart Schaefer
1999-02-03  8:02 Sven Wischnowsky
1999-02-03  8:39 ` Bart Schaefer
1999-02-03  9:55 Sven Wischnowsky
1999-02-03 10:06 Sven Wischnowsky
1999-02-03 10:42 ` Peter Stephenson

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