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



[The road leading to our buildin is build anew and yesterday someone
cut the cable that is our only connection to the main building. Our
system administrators say that everything is working again, although I 
haven't got all the messages from the list, yet. So this is also a test...]

Andrej Borsenkow wrote:

> > - makes the treatment of `${${...}...}' (hopefully) consistent (and
> >   this is a answer to one of Peter's questions above). The rule is:
> >   the inner `${...}' is broken into array elements if it yields more
> >   than one word and the whole thing is not quoted or if it is quoted and
> >   the `@' flag is used. I'd like to hear comments if you think that
> >   this looks and feels like the right thing.
> 
> What do you mean "one word"?

I only meant that one can't `break' *one* word into multiple `array
elements'.

> Array with single element yields one word. And
> it is very important with subscription (that behaves very funny anyway - see
> later). I prefer the case, when array yields array irrespectively of number
> of the elements.



> This is suggestion I had long ago. May be, it is the same, as you mean, but
> explicitly stated:
> 
> without qoutes
> 
>  - ${array} always gives array
>  - ${scalar} always gives scalar
>  - ${array[sub]} gives scalar
>  - ${array[sub1,sub2]} gives array (slice)
>  - ${(split)something} always gives array (may be, with single element)
>  - ${(join)something} always gives scalar
>  - $~ is considred "spliting" in this respect
> 
> in quotes
> 
>  - without (@) all yields scalar
>  - with (@) the result is array _for_the_next_level_ (for those operations,
> that yield array). The point is, the flags and subscription are applied, as
> if it were array - and the result is converted to scalar unless (@) is given
> as well.
> 
> That is, "${${(@)array}[1,3]} gives 1,2,3 elements of array as scalar. And
> "${(@)${(@)array}[1,3]}" - the same, but as three words.

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.

Hence these results:

> ....
> 
> bor@itsrm2:~%> foo=bar
> bor@itsrm2:~%> print ${${foo}[1]}
> bar
> 
> Sorry? Why ${foo} suddenly becomes array?
> 

1) The `${foo}' yields one word and the whole thing is not quoted, so we
get an array for it and that is then subscripted.

> bor@itsrm2:~%> print "${${foo}[1]}"
> b
> 
> With some imagination ...

2) The thing is quoted, we get a scalar and then the first char of it.

> bor@itsrm2:~%> print "${${(@)foo}[1]}"
> b
> 
> ??? Und I always believed, ${(@)foo} is array ...

3) The `(@)' has no effect because `prefork()' doesn't know about it,
gives us no information about it and since the whole thing is in
quotes, we get a scalar for the inner `${...}'.

> bor@itsrm2:~%> print "${(@)${foo}[1]}"
> bar
> 
> Poor, poor ZSH users ...

4) The `(@)' says that the `${foo}' is to be treated as an array, that is 
subscripted, and the result is broken into separate quoted words
(which you won't notice since there is only one).

Ok. Unless someone changes the code so that `multsub()' gets
information from a `paramsubst()' called via `prefork()' we are stuck
with it. But maybe we should add a new flag for the `turn the inner
<whatever> into an array', and make `(@)' work only at the outermost
level with the obvious meaning.

The problem is that this is even more uncompatible with previous
version than what we have now.

Bye
 Sven


--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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