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

Re: values of associations pointed by P flag



On May 22, 10:54pm, Marc Chantreux wrote:
}
} I would like to write a function that compare 2 associative arrays.

I take it this means you'd like to write a function that takes the
names of 2 associative arrays as arguments and compares the contents
of those associations.

} I can use eval but the P flag looks better.

It might, but you misunderstand how it works.  (And the doc could be
clearer, but it all stems from the fact that zsh parameter expansion
works by passing values of parameters, not references to parameters.)

When you write
    hash=( a 1 b 2 )
    x=hash
    print ${${(P)x}[b]}
that's equivalent to writing
    print ${${hash}[b]}
but the value of ${hash} is an ordinary array consisting of all the
values in the associative array.  Consequently you can't subscript
that using the associative array keys.  When instead you write
    print ${(P)x[key]}
that's equivalent to
    print ${(P)${x[key]}}
which in the example above is equivalent to
    print ${h}
because $x is a string and [key] is interpreted as a math expression
with value zero, and the zero'th substring of a string is its first
letter.  Your test happened to partly work only because you used all
variables with single-letter names.

The right answer is that you have to put the subscript into the value
of $x before you apply the (P) flag.
    x="hash[b]"
    print ${(P)x}

So the completed function looks something like

    cmp_hashes() {
	local __k __x __y   # Underscores to avoid name clash
	for __k ( ${(Pk)1} ) {
	    __x="$1""[$__k]" __y="$2""[$__k]"
	    print $__x=${(P)__x} $__y=${(P)__y}
	}
    }

-- 



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