zsh-users
 help / color / mirror / code / Atom feed
* 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

* Re: proxy name for array
  2024-01-10 21:11             ` Bart Schaefer
@ 2024-01-10 21:22               ` Ray Andrews
  0 siblings, 0 replies; 10+ messages in thread
From: Ray Andrews @ 2024-01-10 21:22 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

[-- Attachment #1: Type: text/plain, Size: 738 bytes --]


On 2024-01-10 13:11, Bart Schaefer wrote:
> 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
Agreed.  If I won't have a clue what I was doing in six months then KISS 
is best.
>    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
Once I have this running -- the real function -- I'll try that.
> or even
>
>    set -A "${temp}[2,4]" 50 100 150

No, because in the real function there's work to determine what the 
values will be, they can't be assigned ahead of time.


[-- Attachment #2: Type: text/html, Size: 1552 bytes --]

^ 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).