* proxy name for array
@ 2024-01-09 18:59 Ray Andrews
2024-01-10 0:21 ` Bart Schaefer
0 siblings, 1 reply; 10+ messages in thread
From: Ray Andrews @ 2024-01-09 18:59 UTC (permalink / raw)
To: Zsh Users
[-- Attachment #1: Type: text/plain, Size: 1516 bytes --]
typeset -A body=()
LIST=( one two three four five )
body[array]=LIST
proxy=$body[array] # But name of array could change.
echo $proxy
# Comical efforts included for a laugh ... but you see what I'm
trying to do:
# proxy[2]=TWO
# $~proxy[2]=TWO
# ${(P)proxy[2]}=TWO
# ${(P)proxy}[2]=TWO
# eval "${(P)proxy}[2]=TWO"
# eval "$proxy[2]=TWO"
# eval "${(P)proxy[2]}=TWO"
# eval ${(P)proxy[2]}=TWO
echo 'hoping for: one TWO three four five :-('
echo $LIST # Not changed.
... I'm not sure I've ever attempted anything like the above. I want
'proxy' to hold an arbitrary array name and serve if place of an actual
name. '(P)' does this kind of work on the sending side of an
assignment, but not on the receiving side and I'm not sure you can ever
do an expansion there anyway -- looks bloody awful. But my (usually)
false friend 'eval' works does work like this:
eval "${proxy}[2]=TWO" # ... and having finally nailed it, it's
intuitive and obvious why this works and the monstrosities above do not :-(
echo $LIST # Done!
... But Bart always cautions against it, so I'm wondering if there's a
more kosher way. BTW I had previously been copying entire arrays,
making changes and then copying them back, but why not just use the
proxy name for whatever the actual name of the array might be? This is
'pointer think' of course. And I know we don't officially have pointers
but this is a pretty good approximation.
[-- Attachment #2: Type: text/html, Size: 2025 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: proxy name for array
2024-01-09 18:59 proxy name for array Ray Andrews
@ 2024-01-10 0:21 ` Bart Schaefer
2024-01-10 0:54 ` Ray Andrews
0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2024-01-10 0:21 UTC (permalink / raw)
To: Ray Andrews; +Cc: Zsh Users
On Tue, Jan 9, 2024 at 11:00 AM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> typeset -A body=()
> LIST=( one two three four five )
> body[array]=LIST
> proxy=$body[array] # But name of array could change.
This whole business with body[array] seems irrelevant to the question,
because by the end $proxy is just the name of the array and $body no
longer enters into it. If that's not true you're going to have to
explain yourself better.
> echo $proxy
> # Comical efforts included for a laugh ... but you see what I'm trying to do:
You're encountering two issues:
#1 - the (P) flag only works on identifiers (not array references) and
only for one level of indirection
#2 - assignments don't indirect on the identifier to the left
The way to do this without an eval is to make a new identifier for (P)
to munch on, and then use the syntax that embeds an assignment in a
parameter expansion to get the indirection:
proxy_assign="${proxy}[2]"
: ${(P)proxy_assign::=TWO}
> eval "${proxy}[2]=TWO" # ... and having finally nailed it, it's intuitive and obvious why this works and the monstrosities above do not :-(
>
> ... But Bart always cautions against it, so I'm wondering if there's a more kosher way.
The problem with that particular construct is that you're eval-ing TWO
as well as eval-ing ${proxy}[2], which though harmless in this example
could bite you later. Necessary quoting to account for that might not
be any simpler than using the extra parameter.
The perpetually-delayed next release will include "named references"
which change above issue #2 ...
typeset -n proxy=LIST
proxy[2]=TWO
# Now $LIST[2] is TWO
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: proxy name for array
2024-01-10 0:21 ` Bart Schaefer
@ 2024-01-10 0:54 ` Ray Andrews
2024-01-10 2:29 ` Bart Schaefer
0 siblings, 1 reply; 10+ messages in thread
From: Ray Andrews @ 2024-01-10 0:54 UTC (permalink / raw)
To: zsh-users
[-- Attachment #1: Type: text/plain, Size: 2035 bytes --]
On 2024-01-09 16:21, Bart Schaefer wrote:
> On Tue, Jan 9, 2024 at 11:00 AM Ray Andrews<rayandrews@eastlink.ca> wrote:
>> typeset -A body=()
>> LIST=( one two three four five )
>> body[array]=LIST
>> proxy=$body[array] # But name of array could change.
> This whole business with body[array] seems irrelevant to the question,
> because by the end $proxy is just the name of the array and $body no
> longer enters into it. If that's not true you're going to have to
> explain yourself better.
I have a lot of functions that might have to work with any of several
different arrays, each with it's own name. The guts of the function
naturally needs one name to work with so that name must be a proxy for
whatever the 'real' name of the function is. My tests work ok so I can
do what I want ... with eval.
#2 - assignments don't indirect on the identifier to the left
Yes, I sorta know that. I'm not the least bit surprised all those
efforts failed.
> proxy_assign="${proxy}[2]"
> : ${(P)proxy_assign::=TWO}
I had saved a snippet that looked much like that, but for the life of me
I can't remember what '::=' does, and I didn't make a note of it at the
time which is a mea culpa, and naturally it's impossible to search for
'::=' in the manual or even online. Google for: " zsh '::=' " and get
zero hits. Man I hate that. I'm not lazy, I try to do my own homework
but there's no way of knowing where to look.
Anyway I'll try that on faith.
> The problem with that particular construct is that you're eval-ing TWO
> as well as eval-ing ${proxy}[2], which though harmless in this example
> could bite you later. Necessary quoting to account for that might not
> be any simpler than using the extra parameter.
Yeah, well I already know I'm not going to use eval if I don't have to.
>
> The perpetually-delayed next release will include "named references"
> which change above issue #2 ...
>
> typeset -n proxy=LIST
> proxy[2]=TWO
> # Now $LIST[2] is TWO
>
Cool! Pointers! That would make my issue trivial.
[-- Attachment #2: Type: text/html, Size: 3529 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: proxy name for array
2024-01-10 0:54 ` Ray Andrews
@ 2024-01-10 2:29 ` Bart Schaefer
2024-01-10 2:58 ` Ray Andrews
0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2024-01-10 2:29 UTC (permalink / raw)
To: Ray Andrews; +Cc: zsh-users
On Tue, Jan 9, 2024 at 4:54 PM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
>> proxy_assign="${proxy}[2]"
>> : ${(P)proxy_assign::=TWO}
Actually I just thought of a much more straightforward way to do this.
set -A "${proxy}[2]" TWO
I had always thought "set -A" would complain about needing an
identifier, there, but it doesn't, and the semantics of assigning an
array to an array element make this work.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: proxy name for array
2024-01-10 2:29 ` Bart Schaefer
@ 2024-01-10 2:58 ` Ray Andrews
2024-01-10 3:05 ` Bart Schaefer
0 siblings, 1 reply; 10+ messages in thread
From: Ray Andrews @ 2024-01-10 2:58 UTC (permalink / raw)
To: Bart Schaefer; +Cc: zsh-users
On 2024-01-09 18:29, Bart Schaefer wrote:
> On Tue, Jan 9, 2024 at 4:54 PM Ray Andrews <rayandrews@eastlink.ca> wrote:
>>> proxy_assign="${proxy}[2]"
>>> : ${(P)proxy_assign::=TWO}
> Actually I just thought of a much more straightforward way to do this.
>
> set -A "${proxy}[2]" TWO
>
> I had always thought "set -A" would complain about needing an
> identifier, there, but it doesn't, and the semantics of assigning an
> array to an array element make this work.
Sheesh, that was easy. Only thing is having to chop it up into an array
again:
Run:
LIST=( one two three four five )
echo $LIST
proxy="LIST"
set -A "${proxy}" "onezies toony threeatlast forlorn fivealive"
echo $LIST
LIST=( ${=LIST} )
echo $LIST[2,3]
... gives:
one two three four five
onezies toony threeatlast forlorn fivealive
toony threeatlast
... I wonder if it's smart enough to accept array output directly?
Tried a few things with no luck.
Tx. Bart, would you please give me someplace to read up on " ::= " also
on the leading colon -- for the previous method. I have no idea what
that does but it can't be omitted.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: proxy name for array
2024-01-10 2:58 ` Ray Andrews
@ 2024-01-10 3:05 ` Bart Schaefer
2024-01-10 13:44 ` Ray Andrews
2024-01-10 20:26 ` Ray Andrews
0 siblings, 2 replies; 10+ messages in thread
From: Bart Schaefer @ 2024-01-10 3:05 UTC (permalink / raw)
To: Ray Andrews; +Cc: zsh-users
On Tue, Jan 9, 2024 at 6:58 PM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> set -A "${proxy}" "onezies toony threeatlast forlorn fivealive"
Just don't put quotes around the arguments.
set -A "${proxy}" onezies toony threeatlast forlorn fivealive
Read the doc for "set", the -A option takes a list of words.
> Bart, would you please give me someplace to read up on " ::= "
You really can search for it in the doc. "man zshexpn" and search.
> the leading colon -- for the previous method.
It's a shell builtin command.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: proxy name for array
2024-01-10 3:05 ` Bart Schaefer
@ 2024-01-10 13:44 ` Ray Andrews
2024-01-10 20:26 ` Ray Andrews
1 sibling, 0 replies; 10+ messages in thread
From: Ray Andrews @ 2024-01-10 13:44 UTC (permalink / raw)
To: zsh-users
[-- Attachment #1: Type: text/plain, Size: 465 bytes --]
On 2024-01-09 19:05, Bart Schaefer wrote:
> You really can search for it in the doc. "man zshexpn" and search.
Nuts. It's there as you say, but my favorite online version of the
manual can't find it. I wonder how much grief that's caused me? Maybe
my 'search for syntax' idea is obviated because it's just this
particular HTML version that can't do it. That's irritating.
https://zsh-manual.netlify.app
... very attractive and easy to read but ...
[-- Attachment #2: Type: text/html, Size: 1053 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: proxy name for array
2024-01-10 3:05 ` Bart Schaefer
2024-01-10 13:44 ` Ray Andrews
@ 2024-01-10 20:26 ` Ray Andrews
2024-01-10 21:11 ` Bart Schaefer
1 sibling, 1 reply; 10+ messages in thread
From: Ray Andrews @ 2024-01-10 20:26 UTC (permalink / raw)
To: zsh-users
This works. Double indirection, but she runs.
function called ()
{
# Am I tempting the wrath of the Gods? :
temp=( ${(P)${(P)1}[pages]} ) # Temporary array will be used to
hold content of 'Pages' (or whatever else).
temp[2]=50 # Set some test values.
temp[3]=100
temp[4]=150
echo 10: $temp # How are we doing?
echo 11: $temp[3] # So far so good.
set -A "${${(P)1}[pages]}" $temp # The hard part: write 'temp'
back to 'Pages' via the named input array.
}
typeset -A main=() # The main structure. Contains a dozen elements
but we only need one here ...
main[pages]=Pages # The name of the pages array.
Pages=( 1 ) # Initialize. This is going to end up as an
array of numbers.
# Now we jump into the function that will modify 'Pages' -- or whatever
other name is held in '[pages]' of whatever structure name is passed.
called main # Push the button. Don't look at the flash.
echo 13: ${(P)main[pages]} # It's Alive! It's alive, it's alive,
it's alive!
echo 14: ${(P)main[pages][3]} # Now I know what it's like to be Mark!
;-))
echo "Who said zsh doesn't have structures? She does, they're just a
bit tricky to build."
----------------------------------------------
... subject to improvement of course. Or can 'temp' be avoided by
direct access to 'Pages' but via similar indirection? Probably too
complicated.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: proxy name for array
2024-01-10 20:26 ` Ray Andrews
@ 2024-01-10 21:11 ` Bart Schaefer
2024-01-10 21:22 ` Ray Andrews
0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2024-01-10 21:11 UTC (permalink / raw)
To: Ray Andrews; +Cc: zsh-users
On Wed, Jan 10, 2024 at 12:26 PM Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> temp=( ${(P)${(P)1}[pages]} ) # Temporary array will be used to
> hold content of 'Pages' (or whatever else).
> temp[2]=50 # Set some test values.
Yes, you could avoid temp with
set -A "${${(P)1}[pages]}[2]" 50
set -A "${${(P)1}[pages]}[3]" 100
set -A "${${(P)1}[pages]}[4]" 150
but that's not as clear or easily maintainable. You could also do
temp=${${(P)1}[pages]} # Note one less (P) and not an array
set -A "${temp}[2]" 50
set -A "${temp}[3]" 100
set -A "${temp}[4]" 150
or even
set -A "${temp}[2,4]" 50 100 150
All three of the above would avoid the need to write an entire array
back as the last step, but unless you're dealing with huge arrays the
best form is the one you understand.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-01-10 21:23 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-09 18:59 proxy name for array Ray Andrews
2024-01-10 0:21 ` Bart Schaefer
2024-01-10 0:54 ` Ray Andrews
2024-01-10 2:29 ` Bart Schaefer
2024-01-10 2:58 ` Ray Andrews
2024-01-10 3:05 ` Bart Schaefer
2024-01-10 13:44 ` Ray Andrews
2024-01-10 20:26 ` Ray Andrews
2024-01-10 21:11 ` Bart Schaefer
2024-01-10 21:22 ` Ray Andrews
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).