Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Associative Arrays

* Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> [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.)


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


> 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,

::: 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 :::

Messages sorted by: Reverse Date, Date, Thread, Author