zsh-users
 help / color / mirror / code / Atom feed
From: Ray Andrews <rayandrews@eastlink.ca>
To: zsh-users@zsh.org
Subject: Re: saved from prince of eval
Date: Sun, 08 Nov 2015 14:04:06 -0800	[thread overview]
Message-ID: <563FC6D6.90104@eastlink.ca> (raw)
In-Reply-To: <151108115752.ZM859@torch.brasslantern.com>

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.


  reply	other threads:[~2015-11-08 22:04 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-08 17:07 Ray Andrews
2015-11-08 19:57 ` Bart Schaefer
2015-11-08 22:04   ` Ray Andrews [this message]
2015-11-09  8:50     ` Ray Andrews
2015-11-09 18:41       ` Bart Schaefer
2015-11-10  0:48         ` Ray Andrews
2015-11-11  1:07         ` Ray Andrews
2015-11-11  4:18           ` Bart Schaefer
2015-11-11  5:31             ` Ray Andrews

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=563FC6D6.90104@eastlink.ca \
    --to=rayandrews@eastlink.ca \
    --cc=zsh-users@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).