Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: OPTARG not being set?

On Wed, Feb 03, 1999 at 12:03:02AM -0800, Bart Schaefer wrote:
> Nope.  Nested ${...} constructs don't act like that in zsh; the doc says
> ${NAME}
>     The value, if any, of the parameter NAME is substituted. [...]
>     If a `${'...`}' type parameter expression or a `$('...`)' type command
>     substitution is used in place of NAME above, it is expanded first and
>     the result is used as if it were the value of NAME.
>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	see below for my comments on the syntactic definition of a "name".

> That last phrase is key: the result is not used as if it were a new name,
> it's used as if it were (should say was) 
	actually, were is the correct usage there.  (despite what some
people claim, the subjunctive does exist in english.)

> All the rest of the processing
> specified by flags or modifiers in the outer braces is applied to the
> resulting value string or array.  That's why ${(t)${bob}} doesn't work,
> because a value doesn't have a type; only names have types (which are
> instructions for interpreting the value).
	is the difference between a name and a value semantic instead of
syntactic, then?  i would assume that the shell decides what is a value
and what is a name by the context in which it is placed; based on the
definitions given in the manpage, it seems that ${...} constructs 
definitionally interpret the first token inside the braces to be a name.
after reading over the paragraph you quote above a few times, i can see
how it can be interpreted to mean what you say it means, which is that
nested uses of ${...} override the syntactic identification of the
first token of all but the innermost ${...} as a name, but i don't think
that that is immediately clear (not that my restating of it is any better
to anyone but a logician).  there are, i guess, three ways to possible
make this more understandable:

	1) come up with a better version of the paragraph you quoted,
that at least states explicitly that the nesting causes an exception to
the definitions given just before that paragraph.  with the current
terminology, however, i don't know if it can really be made that clear
no matter how it is worked over, which leads to...
	2) after i sent in my original question, i did a search on the
zsh-workers archive, and noticed that you had done some work on this
same topic, at least in standardizing use of terms like "expansion"
and "substitution".  i think that it would help a lot to do the same
thing for terms like "name", "word", and value"; if that were to be done,
then i think that this could just be explained in the definitions of
the various ${...} constructs themselves, rather than in a footnote
at the end.
	3) i'm not a huge fan of "magic" values and exceptions (which is
one of the reasons that i've never really gotten that into perl); the
third solution, then, would be to make the behaviour of ${...} standard
regardless of whether or not they are nested.  this would break lots of
existing scripts, i'm sure--which is probably why the (P) flag was added,
which leads to...

> What Sven's new (P) flag does is force the value to be interpreted as a
> new name, the way the syntax misled you expect all along.  (Maybe the
> (P) flag ought to be ($), as in ${($)${bob}}.  Or more likely not.)
	is this added in a dev version?  i can't find reference to it
in the 3.1.5 docs.

> } (astaroth)~6: echo ${(e)bob}
> } joe
> } that #6 would explicitly cause parameter expansion and print hello world
> First, note that ${bob} substitutes to "joe".  ${(e)bob} is similar (but
> not identical) to $(echo ${bob}).  
	how so?  according to the docs, (e) says to "[p]erform parameter
expansion, command substitution, and arithmetic expansion on the result."
i originally thought that this meant that ${(e)${bob}} would parse to
${(e)joe}, and then perform parameter expansion on ${joe}--something
akin to `eval echo $(bob)`; when that didn't work, i thought that maybe 
it implicitly assumed that the token following it was a parameter to be 
expanded before the ${...} param expansion took place, which is why i 
tried the version you quoted.  from what you describe, it appears that
(e) just does a command substitution on an echo of the value of the
name passed to it.  when would this be useful?

>What's $(echo joe)?  Why, it's still
> just "joe".  To get the effect you expected, you have to do
> 	bob='$joe'		# Note ${bob} now substitutes $joe
> 	${(e)${bob}}		# Like $(echo $joe) --> hello world

	to do this dynamically (i.e. to get this effect when you don't
know ahead of time that joe is name of the parameter to be expanded),
however, you need to do something like bob="${${param_whose_value_is_joe}}",
which is the original situation that caused me to start trying to figure
all of this out.
> } (astaroth)~7: echo "echo \${$(echo ${bob})}"
> } echo ${joe}
> } (astaroth)~8: `echo "echo \${$(echo ${bob})}"`
> } joe
> } and that #8 would evaluate the results
> } of #7, which would be the same as typing #3, and would
> } thus print hello world.
> Ah, now we're getting into it.  When the `...` expression is parsed, \$
> is converted into just $.  _Then_ the string "echo ${$(echo ${bob})}"
> is parsed, and by the magic of ${$(...)}, resolves to "echo joe", which
> is what finally gets eval'd.
> If instead you said $(echo "echo \${$(echo ${bob})}"), then the \$ is not
> converted into bare $, and the string becomes "echo \${joe}", and the
> result of the whole expression is
> 	${joe}
	which led me to try `eval echo \${$(echo $bob)}', which does work:
it parses to `eval echo \${joe}', strips off the \, and evals `echo ${joe}'.
what i had originally been using, however, was `eval echo \${${bob}}';
the entire point of this exercise was to try to get rid of the eval.
	what is the difference between grave-accent command substitution,
$(...) command substitution, and eval's pseudo-command substitution?  it
looks like grave accents strip meta-char escapes, do param expansion, and 
then evaluate, while $(...) just does param expansion and then evaluates, 
and eval does param expansion, strips meta-char escapes, and then evaluates.
is that the case?  are there any other differences?

	-- sweth.

Sweth Chandramouli
IS Coordinator, The George Washington University
<sweth@xxxxxxx> / (202) 994 - 8521 (V) / (202) 994 - 0458 (F)
<a href="http://astaroth.nit.gwu.edu/~sweth/disc.html";>*</a>

Messages sorted by: Reverse Date, Date, Thread, Author