From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20111 invoked by alias); 2 Nov 2015 19:40:22 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 20877 Received: (qmail 8797 invoked from network); 2 Nov 2015 19:40:20 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1446492832; bh=6gtj3bTsFX8W3eF+Pa/xpVu3xZxhN2Bblqy0+mq0BC8=; h=From:To:In-Reply-To:References:Subject:Date; b=SEYB7NvioYw0pdbANlSZ/WSxhev6OVNF4HnGuVGSEnqi4IA6c1gff4jbVTlSr4VSO 3LYoeMe0tHSRy/zD/57cfYjAhttg9fcIVHbADRAoJjtzseZkG61UUHVWQdkw6jZYTK b1Y37aTRqq+JvDMJfzR41Bu0lsMlFGsPkYQ64cpM= From: ZyX To: Ray Andrews , "zsh-users@zsh.org" In-Reply-To: <563784B5.3040901@eastlink.ca> References: <56369C7B.2030604@eastlink.ca> <1237641446422150@web6m.yandex.ru> <5636B333.8060300@eastlink.ca> <151101190842.ZM16752@torch.brasslantern.com> <5636D99F.2030807@eastlink.ca> <151101225100.ZM16882@torch.brasslantern.com> <563784B5.3040901@eastlink.ca> Subject: Re: easy calling of associative array? MIME-Version: 1.0 Message-Id: <272251446492831@web5o.yandex.ru> X-Mailer: Yamail [ http://yandex.ru ] 5.0 Date: Mon, 02 Nov 2015 22:33:51 +0300 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=utf-8 02.11.2015, 18:45, "Ray Andrews" : > 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.