zsh-users
 help / color / mirror / code / Atom feed
From: ZyX <kp-pav@yandex.ru>
To: Ray Andrews <rayandrews@eastlink.ca>,
	"zsh-users@zsh.org" <zsh-users@zsh.org>
Subject: Re: easy calling of associative array?
Date: Mon, 02 Nov 2015 22:33:51 +0300	[thread overview]
Message-ID: <272251446492831@web5o.yandex.ru> (raw)
In-Reply-To: <563784B5.3040901@eastlink.ca>



02.11.2015, 18:45, "Ray Andrews" <rayandrews@eastlink.ca>:
> On 11/01/2015 10:51 PM, Bart Schaefer wrote:
>>  Anyway, that's actually the point. ${(P)ref} resolves to the values of
>>  the array, and then the subscript is applied. Ask yourself: what are
>>  "the values of" an associative array, in every other context?
>
> I'll give it some time, this is new to me. It seems that with an
> associative array,
> what we have is some 'hidden' syntax, IOW there is a sort of shorthand going
> on. As with math, I'd sorta expect that if this functionality was
> tacked on
> after the fundamentals of the shell were already in place--you leveraged
> what was there--there'd be asymmetries.
>
> Experimenting with trying to make accessing associative arrays convenient:
>
>     echo_v ()
>     {
>     echo ${(P)${:-${1}[$2]}} #this works

    typeset -A foo
    foo=('abc]def' true)
    echo_v foo 'abc]def'
    # Echoes nothing in place of `true`.

. But `key='abc]def' ; echo $foo[$key]` works.

>     #eval "echo \$${1}[$2]" #and this works too.

Thus you need to eval in the following form:

    eval 'echo $'$1'[$2]'

. Without eval I have only came up with

    echo_v()
    {
        emulate -L zsh
        local -A array
        array=( ${(kvP)1} )
        echo $array[$2]
    }

>     }
>
>     get_v ()
>     {
>     #$3=${(P)${:-${1}[$2]}} #nothing works
>     eval "$3=\$${1}[$2]" #this works

Like previous function, but last line should be

        : ${(P)3::=$array[$2]}

in place of `echo $array[$2]`.

With eval you need to use

    eval $3'=$'$1'[$2]'

>     }
>
>     set_v ()
>     {
>     # {(P)${:-${1}[$2]}}=$3 #nothing works
>     eval "${1}[$2]=$3" #this works
>     }

    set_v()
    {
        emulate -L zsh
        local -A array
        array=( ${(kvP)1} $2 $3 )
        : ${(AAP)1::=${(kv)array}}
    }

Note that all my variants without eval are copying array around, eval variants do not.

Eval here:

    eval $1'[$2]=$3'

.

>
>     test_v ()
>     {
>     #eval "${1}[$2]" #nothing works
>                                  #this works
>     [ ${(P)${:-${1}[$2]}} = $3 ] && echo 'all too true' || echo 'alas, no.'

Pretty much obvious after `echo_v`. Note the same problem with 2='abc]def'

>     }
>
> I notice that with 'echo_v' I can use your syntax or 'eval' the thing
> which is
> much easier to read if nothing else. But with 'get_v' and 'set_v' I can
> only make
> it work with 'eval' whereas with 'test_v' I can *not* make it work with
> 'eval'.
> At the risk of being too much of a symmetry nut, is it possible to make
> either
> form work in all the above situations? If so, I have a consistent
> interface to
> these arrays which would be pleasing, but it's an academic point.

Not purely academic. With eval you automatically run in escaping problems (though rather easy to resolve in this case). Without eval you make your code rather unreadable.

>
> FWIW, this is in the context of studying Sebastian's stuff--there's all
> these
> variables sloshing about for each of several zcurses windows, and it
> would be
> C-ish to organize them into arrays, one for each window. However I can
> see that this is at the limits of what a shell should be asked to do, since
> what I really want is a proper C structure for data:
>
> main_window.window_height
>
> becomes:
>
> ${main_window[window_height]}
>
> ... but of course I want to be able to replace 'main_window' with
> any other window via a variable passed to whatever function:
>
> whatever_window->window_height
>
> becomes:
>
> ${(P)${:-${whatever_window}[window_height]}}
>
> ... which looks like it's going to work just so long as I can perform
> any sort
> of operation on the array without difficulty. But there could be speed
> issues
> and the whole thing might not be worth the trouble, but it is educational
> at least.

You can also always use zpython:

echo_v() zpython 'print(zsh.getvalue(zsh.getvalue("1")[0])[zsh.getvalue("2")[0]])'
get_v()  zpython 'zsh.setvalue(zsh.getvalue("3")[0], zsh.getvalue(zsh.getvalue("1")[0])[zsh.getvalue("2")[0]])'
set_v()  zpython 'ret = zsh.getvalue(zsh.getvalue("1")[0]); ret[zsh.getvalue("2")[0]]=zsh.getvalue("3")[0]; zsh.setvalue(zsh.getvalue("1")[0], ret)'

. Pretty much consistent (except that I have no idea why it thinks that all $N parameters are array parameters, but this is consistent with ${(t)1} which returns “array-special”). But again each function is copying parameters around.


  parent reply	other threads:[~2015-11-02 19:40 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-01 23:12 Ray Andrews
2015-11-01 23:55 ` ZyX
2015-11-02  0:49   ` Ray Andrews
2015-11-02  3:08     ` Bart Schaefer
2015-11-02  3:33       ` Ray Andrews
2015-11-02  6:51         ` Bart Schaefer
2015-11-02 15:43           ` Ray Andrews
2015-11-02 16:28             ` Bart Schaefer
2015-11-02 18:32               ` Ray Andrews
2015-11-02 19:37                 ` ZyX
2015-11-02 22:10                   ` Bart Schaefer
2015-11-02 22:50                     ` Ray Andrews
2015-11-02 21:05                 ` Bart Schaefer
2015-11-02 23:01                   ` Ray Andrews
2015-11-03 15:57                     ` Bart Schaefer
2015-11-04 14:48                       ` Ray Andrews
2015-11-04 16:39                         ` Bart Schaefer
2015-11-04 18:31                           ` Ray Andrews
2015-11-02 19:33             ` ZyX [this message]
2015-11-02 23:04               ` 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=272251446492831@web5o.yandex.ru \
    --to=kp-pav@yandex.ru \
    --cc=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).