From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26781 invoked by alias); 27 Feb 2015 18:04:41 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 19931 Received: (qmail 2176 invoked from network); 27 Feb 2015 18:04:37 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:message-id:date:in-reply-to:comments :references:in-reply-to:comments:in-reply-to:comments:to:subject :mime-version:content-type; bh=yDr4ReIl7sgfhwrKYoQB0zxw+AULLZjEQNZN8lWZo2s=; b=jVNHuZ7M2uZVlKEfrbYUhpGS6zVB0Vt+PtrKUjP13GFFwkUwVi4HgGjJQQmncQ6Pp0 tmIcbG93miCPzQTjjKjCoH10L9YZj4f0g6+bCAYL3HEP6Y3iRdhnyBT6H0jyWxFFOqkx 0xMVjpyQ98jy6nBaB/H/lcMckKwcmDJNoZQnD8Bww7kyrfetXh9nlswdt9VGS/pTXs40 8fmO0+gvKdyhvbgs0M3SJKVdGdD56MyNCLET0oNrU+xcZMkyOUKw5LacjKUZrGuiSqnF j0TRUacv0lagAc6ke3RwegjI1WW6DVgoOfCks+qHMFyXjjtzYbiv5jPPEuS1kXl4DjVL qBsA== X-Gm-Message-State: ALoCoQnX0HIkLo1rem0+uKQHYDZHG7lVvRMqYinICDghsrscwNi7aFG7FFQaDaMfMQAIuGNvEK3z X-Received: by 10.202.129.70 with SMTP id c67mr10258360oid.46.1425060273540; Fri, 27 Feb 2015 10:04:33 -0800 (PST) From: Bart Schaefer Message-Id: <150227100430.ZM7974@torch.brasslantern.com> Date: Fri, 27 Feb 2015 10:04:30 -0800 In-Reply-To: <20150227120941.GA15885@fork> Comments: In reply to Jaromil "pointers and associative maps" (Feb 27, 1:09pm) References: <20150227120941.GA15885@fork> <20150227124641.GA17275@fork> <20150227140211.GA18843@fork> In-Reply-To: <20150227124641.GA17275@fork> Comments: In reply to Jaromil "Re: pointers and associative maps" (Feb 27, 1:46pm) In-Reply-To: <20150227140211.GA18843@fork> Comments: In reply to Jaromil "Re: pointers and associative maps" (Feb 27, 3:02pm) X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-users@zsh.org Subject: Re: pointers and associative maps MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Slurping in the whole thread here ... On Feb 27, 1:09pm, Jaromil wrote: } } I'm puzzled by a problem I encounter using pointers and associative } maps. I want to use a variable as pointer for an associative map, then } iterate through the map to get all its values, for saving it to a file } and implement a simple load/save key/value store. The root of some of this confusion may be that zsh doesn't actually have "pointers". With a few special exceptions variables are always resolved to a value as early as possible and thereafter the value is what is passed around and manipulated by parameter flags etc. Furthermore, fundamentally zsh has only two kinds of values: Scalars and arrays. Associative arrays are always resolved to one of those two things -- the scalar at a particular key, the array of all the keys, the array of all the values, the array of alternating keys and values, etc. The (P) flag gives you exactly one level of indirection; "take this value as a name and resolve it to the value at that name before any further processing." It doesn't give you a handle to the thing whose value is resolved. Some of the other flags like (k) and (v) are used at the same level as (P) so that (Pk) gives you the keys of a named array; other flags are applied later, all depending on the order of the expansion rules described in the manual. Thus you can't use (P) on the name of an associative array to get a thing that still behaves like an associative array. You already dealt with that particular detail by iterating on a numeric index instead of using the keys, so perhaps all the foregoing is just background for other interested readers. On Feb 27, 1:46pm, Jaromil wrote: } } solved! using ${(Pv)${_map}[$c]} Sadly, no. As you later discovered, the above only "works" because (unless KSH_ARRAYS) the value of ${hash} is the same as the value of ${(v)hash}. You did in fact want ${${(Pv)_map}[$c]} all along, see below. On Feb 27, 3:02pm, Jaromil wrote: } } puzzling enough, after running the function one can do: } } print ${${(Pk)_map}[$c]} } } please note that having the (Pk) modifier in the inner brackets when } run inside the function does not work at all, rather indexes single } chars in the key/value retrieved (as mentioned in my first post) That's a quoting issue. ${${(Pk)_map}[$c]} and "${${(Pk)_map}[$c]}" are not the same thing; adding the double quotes forces the value to be interpreted as a scalar instead of an array, so the subcript [$c] indexes into the scalar string instead of into the array. You can use "${${(Pk@)_map}[$c]}" to force the index to use the array rather than the scalar, or (depending on context) you can remove the double quotes as you did at the shell prompt. The formulation ${(Pk)${_map}[$c]} first gets the array of values for ${(P)${_map}} and then gives you the key at index [$c], which because of the conversion to a plain array is just $c back again. Any other nesting will either attach (k) to ${_map} or separate (k) from one of (P) or [$c], and thereby produce a different result. % c=2 % print ${(Pk)${_map}[$c]} ${(k)${(P)_map}[$c]} ${${(Pk)_map}[$c]} 2 value2 key2 Some other formulations may leave you scratching your head until you realize that (v) and (k) are no-ops on scalars and [$c] has already reduced the result to a scalar. One other tidbit - given: typeset -A hash hash=(key1 value1 key2 value2) print ${(k)hash} print ${(v)hash} Here the keys and values are guaranteed to come out in corresponding sequence, but might come out in a different order than added: key2 key1 value2 value1 However, given: print ${(k)hash} hash+=(key3 value3) print ${(v)hash} You *might* get e.g.: key2 key1 value1 value3 value2 That is, the order of old keys/values is not guaranteed to stay the same after new keys/values are added. -- Barton E. Schaefer