Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: saved from prince of eval
On 11/08/2015 11:57 AM, Bart Schaefer wrote:
If you haven't already, you should read through the "Rules" section
under "Parameter Expansion". "man zshexpn" and search for "Rules".
Indeed. I've bounced off it several times, it's the thickest of the
thick. Yes, I'll bone up and master it.
In particular the last sentence of the #1 rule "Nested Substitution":
... Note that, unless the '(P)'
flag is present, the flags and any subscripts apply directly to
the value of the nested substitution; for example, the expan-
sion ${${foo}} behaves exactly the same as ${foo}.
Then note that (e) isn't applied until nearly the end of the procedure,
at rule #10.
So in this expression:
} 1: $ foo="${(e)${array}[${top}, ${bottom}]}"
First ${array} expands, and then [$[top},${bottom}] applies to that
value -- which isn't an array, it's a string, so the subscripts are
extracting a range of characters from that string. Finally that
substring is re-evaluated (but probably is nothing interesting).
Yes, by gum. Running diagnostics, there were several times when what
was printed were just a few chars. I didn't even try to make sense of it.
I have no idea why you want to put yourself in that situation,
It seems unavoidable if I'm to use arrays to pass values to functions.
foo='\$${IN[list]}[${IN[topE]}, ${IN[bottomE]}]'
IN[PAGE]="${(e)$(print -R "${(e)${foo}}")}"
... 'IN' is the array copied by value from whatever array holds the data
for the particular window in play. So in the above, I'm setting the
contents of the current displayed page to a range from within the entire
available data which is stored in the array who's name is held in '
IN[list]' (and which varies depending on the window). It's called like this:
set -A IN ${(kv)main} # The window in play has all it's data in
the array 'main'.
n_list_draw 0 1
In the original, it's done like this:
n-list-draw "$(( (NLIST_CURRENT_IDX-1) % page_height + 1 ))" \
"$page_height" "$page_width" 0 1 "$NLIST_TEXT_OFFSET" inner
ansi \
"${(@)col_list[NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN, end_idx]}"
... and of course there are all the local values in the function to
receive the arguments, and at the end of the function all the changes
have to recaptured to specific variables depending on the window.
Mine seems simpler, however I'm open to any suggestion. I quite
understand that I'm pushing zsh past it's natural comfort zone, but it
does seem to be working, it's readable and extendable, but there might
be an entirely different and better way of going about it.
You can replace the $(...) with another ${(e)...} to get your third
needed re-evaluation, and you don't need the inermost ${ } around bar:
foo="${(e)${(e)${(e)bar}}}"
Marvelous. It seems a bit of a labor, but it's understandable. Puts me
in mind to ask why we can't have the 'expand everything in one go' flag:
foo="$(E)bar}
Again it's pretty ridiculous that you're doing anything like this in
the first place.
As above, is there a better way? I confess again that I'm trying to
make zsh into C, but I'm getting away with it. Why shouldn't structured
programming be available in zsh?
} $ foo='stranger'
} $ bar='echo howdy $foo'
} $ eval baz=$bar; echo $baz
} zsh: command not found: howdy << Ferkrissakes
Well, think about it a bit harder. Or better yet, "setopt xtrace" and
watch what is happening.
I understand what eval is doing, my point is just that it's hardly the
safe thing when all I want to do is set a parameter from another
parameter than contains parameters itself. Of course there are times
when we want eval, but setting a parameter ain't it. (e) is it.
Thanks Bart, a superb explanation as always.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author