zsh-users
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Ray Andrews <rayandrews@eastlink.ca>
Cc: Zsh Users <zsh-users@zsh.org>
Subject: Re: associative array questions
Date: Sun, 11 Dec 2022 11:53:16 -0800	[thread overview]
Message-ID: <CAH+w=7Z7WPNwWFGft7u9N3=anVT5pJyhG3QXHh-W2nLsbgDFMQ@mail.gmail.com> (raw)
In-Reply-To: <d9db366e-374f-8135-3d78-132a51bf0d06@eastlink.ca>

On Sun, Dec 11, 2022 at 9:40 AM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
>[...] C-brained as I am, I'm wanting to link to
> the input array directly via a pointer sort of operation so in test3 I'm
> trying to grab the name of the target array and modify it (the array)
> directly.

There are no pointers to data structures in zsh.  Parameter reference
is always by value.  Even ${(P)other} returns a value, it's just the
value of the parameter whose name is in turn the value of $other.
Anything you do with the result of ${(P)other} acts on that value, not
on the indirectly-named parameter itself.

There is one sort-of exception:  The ${NAME=WORD} and related
assign-and-substitute operations.  E.g., if you use
${(P)other::=text}, then the parameter named by $other is assigned the
value "text".  I say this is only sort-of an exception because if
$other names an array, you can only assign to the entire array, not to
individual subscripted fields.

If you want to assign indirectly to a particular field (whether a
position in an ordinary array or a named element in an associative)
you have to store the entire subscript expression in $other, such as
  other="aa[second]"
  : ${(P)other::='tea for two'}

>      print "aa[second] is: ${${(P)aarray}[second]}"

Incidentally, this doesn't work in zsh earlier than 5.2.  Even in 5.9,
it doesn't carry over into the ${NAME=WORD} construct.

> # BAD:
> #    ${(P)aarray}[second]='tea for two'

Assignments are only parsed as such when there is an identifier
(string of nothing but alphanumerics or underscore, plus optional
subscript) to the left of the equal sign BEFORE any substitutions are
performed.  So this doesn't "look like" an assignment to the parser.

Lacking the outer ${...} enclosing the subscript, ${(P)aarray} expands
to all the values of the pointed-to associative array, and you get the
equivalent of

  "1" "two" "three blind mice"[second]

> # GOOD:
>      eval "${aarray}[second]='tea for two'"

In this case the "eval" turns the command into

  aa[second]='tea for two'

which satisfies the "identifier to the left" rule.

You could also do (another thing that doesn't work in older zsh)

  eval "${aarray}+=([second]='tea for two')"

> '${(P)aarray'} should expand to 'aa' remembering that it's a variable

Nope.  It expands to a value, not a variable reference.  Zsh doesn't
(yet) have what ksh calls "namerefs" ... block out everything you know
about pointers in C.

> also unexpected that the array prints upside down:

Associative arrays are unordered hash tables.  It might print "upside
down" or "inside out" depending on what keys are present.  They're
only even called "arrays" because that's how the value behaves if you
omit the subscript.


  reply	other threads:[~2022-12-11 19:54 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-11 17:39 Ray Andrews
2022-12-11 19:53 ` Bart Schaefer [this message]
2022-12-11 20:51   ` Ray Andrews
2022-12-11 21:41     ` Bart Schaefer
2022-12-11 22:37       ` Ray Andrews
2022-12-12  1:52         ` Bart Schaefer
2022-12-12  3:09           ` Ray Andrews
2022-12-13  3:31       ` Ray Andrews
2022-12-13  4:39         ` Bart Schaefer
2022-12-13 16:11           ` Ray Andrews
2022-12-13 16:22             ` Roman Perepelitsa
2022-12-13 20:00               ` Ray Andrews
2022-12-13 20:06                 ` Roman Perepelitsa
2022-12-13 22:47                   ` Ray Andrews
2022-12-13 23:06                     ` Bart Schaefer
2022-12-14  1:08                       ` Ray Andrews
2022-12-13 21:18             ` Bart Schaefer

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='CAH+w=7Z7WPNwWFGft7u9N3=anVT5pJyhG3QXHh-W2nLsbgDFMQ@mail.gmail.com' \
    --to=schaefer@brasslantern.com \
    --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).