zsh-users
 help / color / mirror / code / Atom feed
* Associative Arrays
@ 2004-10-20 19:53 Nikolai Weibull
  2004-10-21 11:05 ` Stephane Chazelas
  0 siblings, 1 reply; 10+ messages in thread
From: Nikolai Weibull @ 2004-10-20 19:53 UTC (permalink / raw)
  To: zsh-users

I'm have a few questions regarding associative arrays.  What exactly is
the A flag for parameter expansion for?  I mean, how does one use it,
and how does one use the AA flag?

Is there any way to pass an associative array as ONE argument to a
function and easily deal with it as the same associative array in the
other function?  The easiest way seems to be the "pass-by-reference"
technique, where one simply passes the name of the array and then use
the P flag to deal with it.
	nikolai


--
::: name: Nikolai Weibull    :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA    :: loc atm: Gothenburg, Sweden    :::
::: page: www.pcppopper.org  :: fun atm: gf,lps,ruby,lisp,war3 :::
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-20 19:53 Associative Arrays Nikolai Weibull
@ 2004-10-21 11:05 ` Stephane Chazelas
  2004-10-21 12:38   ` Nikolai Weibull
  0 siblings, 1 reply; 10+ messages in thread
From: Stephane Chazelas @ 2004-10-21 11:05 UTC (permalink / raw)
  To: zsh-users

On Wed, Oct 20, 2004 at 09:53:48PM +0200, Nikolai Weibull wrote:
> I'm have a few questions regarding associative arrays.  What exactly is
> the A flag for parameter expansion for?  I mean, how does one use it,
> and how does one use the AA flag?

Not very useful, except maybe to avoid the use of typeset.

typeset -A a
a=(foo bar)

can be written:

: ${(AA)=a::=foo bar}

> Is there any way to pass an associative array as ONE argument to a
> function and easily deal with it as the same associative array in the
> other function?  The easiest way seems to be the "pass-by-reference"
> technique, where one simply passes the name of the array and then use
> the P flag to deal with it.
> 	nikolai


You could use "${${(@qqkv)A}[*]}"
$ typeset -A A
$ A=("foo" "b bar" \' \" "" q)
$ print -lr "${${(@qqkv)A}[*]}"
'' 'q' 'foo' 'b bar' ''\''' '"'

So that in the function you can have

typeset -A local_hash
eval "local_hash=($1)"

or:

typeset -A local_hash
local_hash=("${(Q@)${(z)1}}")

-- 
Stephane


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-21 11:05 ` Stephane Chazelas
@ 2004-10-21 12:38   ` Nikolai Weibull
  2004-10-21 16:40     ` Bart Schaefer
  2004-10-21 23:22     ` Eric Mangold
  0 siblings, 2 replies; 10+ messages in thread
From: Nikolai Weibull @ 2004-10-21 12:38 UTC (permalink / raw)
  To: zsh-users

* Stephane Chazelas <Stephane.Chazelas@morse.com> [Oct 21, 2004 13:10]:
> > I'm have a few questions regarding associative arrays.  What exactly is
> > the A flag for parameter expansion for?  I mean, how does one use it,
> > and how does one use the AA flag?
>
> Not very useful, except maybe to avoid the use of typeset.
>
> typeset -A a
> a=(foo bar)
>
> can be written:
>
> : ${(AA)=a::=foo bar}

aha, OK.  How very useful.

> > Is there any way to pass an associative array as ONE argument to a
> > function and easily deal with it as the same associative array in the
> > other function?  The easiest way seems to be the "pass-by-reference"
> > technique, where one simply passes the name of the array and then use
> > the P flag to deal with it.

> You could use "${${(@qqkv)A}[*]}"
> $ typeset -A A
> $ A=("foo" "b bar" \' \" "" q)
> $ print -lr "${${(@qqkv)A}[*]}"
> '' 'q' 'foo' 'b bar' ''\''' '"'

> So that in the function you can have
>
> typeset -A local_hash
> eval "local_hash=($1)"
>
> or:
>
> typeset -A local_hash
> local_hash=("${(Q@)${(z)1}}")

Aha, double quotation and then dequoting.  What a bitch...is this
seriously the simplest/only ways to do it?  I'd say that shell
programming would be a lot simpler as a whole if this was simpler.
Still, I guess I'm thinking a bit too much like a Ruby or C programmer.
	nikolai

--
::: name: Nikolai Weibull    :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA    :: loc atm: Gothenburg, Sweden    :::
::: page: www.pcppopper.org  :: fun atm: gf,lps,ruby,lisp,war3 :::
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-21 12:38   ` Nikolai Weibull
@ 2004-10-21 16:40     ` Bart Schaefer
  2004-10-21 20:22       ` Nikolai Weibull
  2004-10-22 12:32       ` Stephane Chazelas
  2004-10-21 23:22     ` Eric Mangold
  1 sibling, 2 replies; 10+ messages in thread
From: Bart Schaefer @ 2004-10-21 16:40 UTC (permalink / raw)
  To: Nikolai Weibull; +Cc: zsh-users

On Thu, 21 Oct 2004, Nikolai Weibull wrote:

> * Stephane Chazelas <Stephane.Chazelas@morse.com> [Oct 21, 2004 13:10]:
> > > I'm have a few questions regarding associative arrays.  What exactly 
> > > is the A flag for parameter expansion for?  I mean, how does one use 
> > > it, and how does one use the AA flag?
> >
> > : ${(AA)=a::=foo bar}
> 
> aha, OK.  How very useful.

Obviously one would be more likely to use it as ${(AA)=a:=foo bar} (note
only one colon) where it assigns only if the hash is empty.

> > > Is there any way to pass an associative array as ONE argument to a 
> > > function and easily deal with it as the same associative array in 
> > > the other function?

I note in passing that this is not just an issue with associative arrays. 
The shell language (not just zsh's language) in general lacks a way to 
truly pass by reference rather than by value.

> > > The easiest way seems to be the "pass-by-reference" technique, where 
> > > one simply passes the name of the array and then use the P flag to 
> > > deal with it.

That's one way.  Another way is simply to make use of dynamic scoping, so
that the called function treats the variable as global, and the calling
function restricts the scope when necessary.  Part of the function's API
then becomes the name of the variable that it expects to manipulate.

(This is one reason why ksh has "namerefs" so that you can explicitly 
alias two names to the same value, which is after all what happens 
implicitly in other languages when a call-by-reference parameter is 
passed.)

Or am I misreading the question?  Are you asking how to pass-by-value an
associative array?

> > You could use "${${(@qqkv)A}[*]}"
> >
> > So that in the function you can have
> >
> > typeset -A local_hash
> > local_hash=("${(Q@)${(z)1}}")
> 
> Aha, double quotation and then dequoting.  What a bitch...is this
> seriously the simplest/only ways to do it?

If you want to pass its entire value as a single positional parameter, 
that's pretty close to the only way.  However, you have the entire set
of positional parameters to play with.

Think like a Perl programmer, and imagine you're trying to pass a set of 
name-value pairs as @_.  You'd probably write something like

 sub blather {
   my $unnamed1 = shift;
   my $unnamed2 = shift;
   my %named = @_;
   if ($named{'winnie'} eq 'pooh') { print "Oh, stuff and bother\n"; }
 }

So in zsh that'd be

 function blather {
   local unnamed1=$1; shift
   local unnamed2=$2; shift
   local -A named; set -A named "$@"
   if [[ $named[winnie] = pooh ]]; then print "Oh, stuff and bother\n"; fi
 }

> I'd say that shell programming would be a lot simpler as a whole if this 
> was simpler.

Hey, it's only been a few years now that shells have had associative 
arrays AT ALL.  Imagine what shell programming was like in the old days.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-21 16:40     ` Bart Schaefer
@ 2004-10-21 20:22       ` Nikolai Weibull
  2004-10-22 12:32       ` Stephane Chazelas
  1 sibling, 0 replies; 10+ messages in thread
From: Nikolai Weibull @ 2004-10-21 20:22 UTC (permalink / raw)
  To: zsh-users

* Bart Schaefer <schaefer@brasslantern.com> [Oct 21, 2004 18:50]:
> Obviously one would be more likely to use it as ${(AA)=a:=foo bar}
> (note only one colon) where it assigns only if the hash is empty.

> > > > Is there any way to pass an associative array as ONE argument to
> > > > a function and easily deal with it as the same associative array
> > > > in the other function?

> I note in passing that this is not just an issue with associative
> arrays.  The shell language (not just zsh's language) in general lacks
> a way to truly pass by reference rather than by value.

> > > > The easiest way seems to be the "pass-by-reference" technique,
> > > > where one simply passes the name of the array and then use the P
> > > > flag to deal with it.

> That's one way.  Another way is simply to make use of dynamic scoping,
> so that the called function treats the variable as global, and the
> calling function restricts the scope when necessary.  Part of the
> function's API then becomes the name of the variable that it expects
> to manipulate.

Yes, precisely.  That's the way I implemented it.  I guess if elisp gets
away with it, then so should zsh.

> (This is one reason why ksh has "namerefs" so that you can explicitly
> alias two names to the same value, which is after all what happens
> implicitly in other languages when a call-by-reference parameter is
> passed.)

Mm.

> Or am I misreading the question?  Are you asking how to pass-by-value an
> associative array?

Either, or; whatever works.

> > > You could use "${${(@qqkv)A}[*]}"

> > > So that in the function you can have

> > > typeset -A local_hash
> > > local_hash=("${(Q@)${(z)1}}")

> > Aha, double quotation and then dequoting.  What a bitch...is this
> > seriously the simplest/only ways to do it?

> If you want to pass its entire value as a single positional parameter,
> that's pretty close to the only way.

OK.

> However, you have the entire set of positional parameters to play with.

> Think like a Perl programmer,

I try not to.

> and imagine you're trying to pass a set of name-value pairs as @_.
> You'd probably write something like

>  sub blather {
>    my $unnamed1 = shift;
>    my $unnamed2 = shift;
>    my %named = @_;
>    if ($named{'winnie'} eq 'pooh') { print "Oh, stuff and bother\n"; }
>  }

> So in zsh that'd be

>  function blather {
>    local unnamed1=$1; shift
>    local unnamed2=$2; shift
>    local -A named; set -A named "$@"
>    if [[ $named[winnie] = pooh ]]; then print "Oh, stuff and bother\n"; fi
>  }

> > I'd say that shell programming would be a lot simpler as a whole if this
> > was simpler.

> Hey, it's only been a few years now that shells have had associative
> arrays AT ALL.  Imagine what shell programming was like in the old days.

Yes, I know...scary stuff ;-).  Anyway, thanks for the tips.  The Perl
@_-like argument passing style might actually have its merrits,
	nikolai

--
::: name: Nikolai Weibull    :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA    :: loc atm: Gothenburg, Sweden    :::
::: page: www.pcppopper.org  :: fun atm: gf,lps,ruby,lisp,war3 :::
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-21 12:38   ` Nikolai Weibull
  2004-10-21 16:40     ` Bart Schaefer
@ 2004-10-21 23:22     ` Eric Mangold
  2004-10-22  0:08       ` Nikolai Weibull
  1 sibling, 1 reply; 10+ messages in thread
From: Eric Mangold @ 2004-10-21 23:22 UTC (permalink / raw)
  To: Nikolai Weibull, zsh-users

On Thu, 21 Oct 2004 14:38:35 +0200, Nikolai Weibull  
<zsh-users-list@pcppopper.org> wrote:

...

> Aha, double quotation and then dequoting.  What a bitch...is this
> seriously the simplest/only ways to do it?  I'd say that shell
> programming would be a lot simpler as a whole if this was simpler.
> Still, I guess I'm thinking a bit too much like a Ruby or C programmer.
> 	nikolai

Alternatively, you may be trying to fit a shell language on to a problem  
it isn't suited for.

What are you writing?

-Eric



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-21 23:22     ` Eric Mangold
@ 2004-10-22  0:08       ` Nikolai Weibull
  0 siblings, 0 replies; 10+ messages in thread
From: Nikolai Weibull @ 2004-10-22  0:08 UTC (permalink / raw)
  To: zsh-users

* Eric Mangold <teratorn@world-net.net> [Oct 22, 2004 01:58]:
> >Aha, double quotation and then dequoting.  What a bitch...is this
> >seriously the simplest/only ways to do it?  I'd say that shell
> >programming would be a lot simpler as a whole if this was simpler.
> >Still, I guess I'm thinking a bit too much like a Ruby or C programmer.

> Alternatively, you may be trying to fit a shell language on to a problem
> it isn't suited for.

Well, not really.  Most of what I'm trying to do is shell related.  I'm
just trying to write shell scripts that have nice interfaces and such -
not just the "a quick hack" feel to them.

> What are you writing?

Basically, I'm writing a "library" of stuff that eases the creation of
well-working shell scripts.  I'll post something when I have something
decent to show,
	nikolai
--
::: name: Nikolai Weibull    :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA    :: loc atm: Gothenburg, Sweden    :::
::: page: www.pcppopper.org  :: fun atm: gf,lps,ruby,lisp,war3 :::
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-21 16:40     ` Bart Schaefer
  2004-10-21 20:22       ` Nikolai Weibull
@ 2004-10-22 12:32       ` Stephane Chazelas
  2004-10-22 15:07         ` Bart Schaefer
  1 sibling, 1 reply; 10+ messages in thread
From: Stephane Chazelas @ 2004-10-22 12:32 UTC (permalink / raw)
  To: zsh-users; +Cc: Nikolai Weibull

On Thu, Oct 21, 2004 at 09:40:14AM -0700, Bart Schaefer wrote:
[...]
>    local -A named; set -A named "$@"
[...]

That's not correct as "$@" may have "-x"/"-e" like elements.

ksh has:

set -A named -- "$@"

it doesn't seem to work in zsh 4.2.0.

named=("$@")

is OK though.

-- 
Stephane


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-22 12:32       ` Stephane Chazelas
@ 2004-10-22 15:07         ` Bart Schaefer
  2004-10-25 13:14           ` Stephane Chazelas
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2004-10-22 15:07 UTC (permalink / raw)
  To: zsh-users; +Cc: Nikolai Weibull

On Fri, 22 Oct 2004, Stephane Chazelas wrote:

> On Thu, Oct 21, 2004 at 09:40:14AM -0700, Bart Schaefer wrote:
> [...]
> >    local -A named; set -A named "$@"
> [...]
> 
> That's not correct as "$@" may have "-x"/"-e" like elements.

You'd be right if we weren't talking about zsh.  From the doc for "set":

     The behaviour of arguments after -A NAME or +A NAME depends on
     whether the option KSH_ARRAYS is set.  If it is not set, all
     arguments following NAME are treated as values for the array,
     regardless of their form.  If the option is set, normal option
     processing continues at that point; only regular arguments are
     treated as values for the array.  This means that

          set -A array -x -- foo

     sets array to `-x - foo' if KSH_ARRAYS is not set, but sets the
     array to foo and turns on the option `-x' if it is set.

> ksh has:
> 
> set -A named -- "$@"
> 
> it doesn't seem to work in zsh 4.2.0.

See above.

> named=("$@")
> 
> is OK though.

I'll agree it's better because it doesn't vary with KSH_ARRAYS.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Associative Arrays
  2004-10-22 15:07         ` Bart Schaefer
@ 2004-10-25 13:14           ` Stephane Chazelas
  0 siblings, 0 replies; 10+ messages in thread
From: Stephane Chazelas @ 2004-10-25 13:14 UTC (permalink / raw)
  To: zsh-users, Nikolai Weibull

On Fri, Oct 22, 2004 at 08:07:13AM -0700, Bart Schaefer wrote:
[...]
>      The behaviour of arguments after -A NAME or +A NAME depends on
>      whether the option KSH_ARRAYS is set.  If it is not set, all
>      arguments following NAME are treated as values for the array,
>      regardless of their form.  If the option is set, normal option
>      processing continues at that point; only regular arguments are
>      treated as values for the array.  This means that
> 
>           set -A array -x -- foo
> 
>      sets array to `-x - foo' if KSH_ARRAYS is not set, but sets the
>      array to foo and turns on the option `-x' if it is set.
[...]

You're right. I was wrong.

I had tested:
set -A a -- foo
echo $a
(but not in ksh compatibility mode)

and
set -A a -e foo
echo $a

And of course, the "-e" was grabbed by echo...

Sorry for that,
Stephane


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2004-10-25 13:15 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-20 19:53 Associative Arrays Nikolai Weibull
2004-10-21 11:05 ` Stephane Chazelas
2004-10-21 12:38   ` Nikolai Weibull
2004-10-21 16:40     ` Bart Schaefer
2004-10-21 20:22       ` Nikolai Weibull
2004-10-22 12:32       ` Stephane Chazelas
2004-10-22 15:07         ` Bart Schaefer
2004-10-25 13:14           ` Stephane Chazelas
2004-10-21 23:22     ` Eric Mangold
2004-10-22  0:08       ` Nikolai Weibull

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