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.
next prev 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).