From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Bart Schaefer" Message-Id: <990203000302.ZM10072@candle.brasslantern.com> Date: Wed, 3 Feb 1999 00:03:02 -0800 To: Sweth Chandramouli , zsh-users@math.gatech.edu Subject: Re: OPTARG not being set? MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailing-List: 2067 On Feb 2, 10:56pm, Sweth Chandramouli wrote: } Subject: Re: OPTARG not being set? } } (astaroth)~1: joe='hello world' } (astaroth)~2: bob=joe } (astaroth)~3: echo ${joe} } hello world } (astaroth)~4: echo ${bob} } joe } (astaroth)~5: echo ${${bob}} } joe } i would think that #5 should print hello world 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. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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) the _value_. (This is, IMO, not very intuitive -- had I been designing the syntax, I would have scrapped the inner `$' and nested only the braces; but then nested parameter name substitution would not parallel $(...) substitution inside ${...}, which is a different potential source of confusion.) Thus only the innermost NAME is actually looked up in the parameter table (or command substituted, or whatever). 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). 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.) } (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}). 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 } (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 is still not what you wanted. It's very tricky to get backslashes to be removed exactly when you want them to, because of the interactions among the various kinds of quoting. -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.brasslantern.com