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

RE: PATCH: param stuff and was: PATCH: 3.1.5-pws-12: _brace_parameter



Andrej Borsenkow wrote:

> > This ounds good, but can't be done easily (I think). The problem is
> > that in the case of a `${${...}...}' the code currently just takes the
> > inner `${...}' and calls `prefork()' on it (which does most of the
> > expansions). The result is a list of strings and no other
> > information. So here, the result of an one-element array and an scalar
> > is indistinguishable. This means that we have to say in the *outer*
> > `${...}' if we want the result of the inner one to be treated as an array.
> 
> Can I formulate it as: every substitution is done as if it were the
> top-level one?

As a wish? Yes, and as I said, I'd like to have this, too.

> >
> > The problem is that this is even more uncompatible with previous
> > version than what we have now.
> >
> 
> The problem ZSH always had (and have) is very poor documentation. I think,
> the (partial) reason for it is, nobody actually knows, how it behaves. New
> features are added on ad-hoc basis, without clear picture, how the whole
> works.

This isn't a new feature, it is an attempt at making things more
consistent, more usable. Before the patches I made There was no way to 
get the inner `${...}' be treated as an array. I found this when
implementing `_long_options' where I had an expression roughly like
`${${(P)foo}[1]}'. At one point the array whose name was stored in
`foo' happened to have only one element and suddenly I got the first
character of it, not the whole element -- and there was no way to get
it. With the changed code `${(@)${(P)foo}[1]}' this works.

> Currently there are several ZSH wizards that either know all ins and outs by
> heart or know source code. It is virtually impossible for ordinary user to
> use the power ZSH provides, because the only way to do it is by trial and
> error. You never can tell, what is a result of a (mildly complicated)
> expression simply by looking at it.
> 
> Can anybody explain (in the manual) how ZSH substitution really works?
> Returning to my example:
> 
> bor@itsrm2:~%> foo=(bar baz)
> bor@itsrm2:~%> print "${(@)${foo}[1]}"
> bar baz
> bor@itsrm2:~%> print "${${(@)foo}[1]}"
> b
> 
> Could anybody explain, why? We take the value of foo, that is (bar baz). The
> whole is quoted, so it is converted to scalar. Then, all of a sudden, this
> scalar is converted back to array! Why?  What about second? On the top
> level, (@) prevents array->scalar converting:
> 
> bor@itsrm2:~%> print -l "${(@)foo}"
> bar
> baz
> 
> But why it does not happen with inner ${(@)foo} in the above case? How can I
> take array slice in double quotes?

Because (as I said in the part of my message you quoted at the top),
the outer one doesn't say that the inenr one should be treated as an
array:

  % foo=(bar baz)
  % echo "${(@)${(@)foo}[1]}"
  bar

The behavior is consistent in that in quotes you need a `(@)' in the
outer one to get the inner one split. That's all. And, as I said in a
part of the message you didn't quote I agree that this is a bit ugly
since the `(@)' has two meanings. In my example: the inner `${...}' is 
splitted into two strings due to the `(@)' in the inner expression.
Then the `(@)' in the outer expression ensures that these strings are
treated as different elements by the subscript. And finally, if we had 
a subscript selecting more than one element or no subscript at all,
the `(@)' in the outer expression would also make the result be
treated as separate strings by the `echo'.

> That is only one example of inconsistency. The answer "it is implemented
> this way" is very weak argument. What I'd like to hear - *why* is it
> implemented this way.

Because noone yet took the time to implement it differently... But
seriously: I'm pretty sure noone would object if you (or someone else) 
changes the way the inner expression is expanded as long as it does
not differ from what we have now (or before my patches) in the simple
cases. Having this cleaned up would be nice, indeed. If I were to
implement this I'd probably play with calling `paramsubst()' directly
in `multsub()' if the things starts with `${'. And then I'd have to
think a lot about and play a lot with a inner `$(...)' where we have
the problem that they can't have flags, so with them we *will* have to 
specify in the outer `${...}' what should be done with the result of
expanding it -- if we need different ways.
I'm not that unlucky with the current behavior and too busy in other
parts of the code (you may have noticed ;-), so I won't do more work
here now...

Bye
 Sven


--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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