zsh-users
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh-users@zsh.org
Subject: PATCH and more remarks on parameter expansion docs
Date: Tue, 01 Jan 2013 21:15:01 -0800	[thread overview]
Message-ID: <130101211501.ZM3814@torch.brasslantern.com> (raw)
In-Reply-To: <20121231233002.GC2054@localhost.localdomain>

Collecting a few threads about parameter expansion here in order to make
some other remarks.

On Jan 1,  7:30am, Han Pingtian wrote:
} Subject: Re: Creating A Clean Environment For Autoloaded Functions
}
} >       # Requires zsh 5.0, otherwise you need a loop
} >       zmodload -u ${(k)modules[(R)loaded]:|existing_modules}
} 
} How could we know that, the "(k)" will be run before ":|" here, please?
} Because "k" will be applied with the subscripting, so it will be before
} the ":|" ?

That's correct.  I've added some mention of this in the patch below.

On Dec 27,  3:08pm, Han Pingtian wrote:
} Subject: Re: splitting in assignment forms of expansion
}
} I think we should say something like this about this feature in the man
} page:
}
}     Note during assignments with the A flag, that splitting is applied 
}     to word in the assignment forms of spec before the assignment to
}     name is performed. This will affects the result.

I added something similar in the patch.

In looking through the parameter flags to see what else may have been
overlooked in the "rules", I found no mention of the (c) and (t) flags.

The (c) flag does what Han Pingtian was asking about in the thread Re:
priority problem of ":|" and ":*" --

    % x=(a b c)
    % print "${#x}" ${(c)#x}
    % 3 5

That is, (c) joins up the array for length purposes even in places where
it would not normally be joined.  I've expanded the doc for this a little
as well, but I didn't explicitly mention it in the rules section because
it only matters in combination with "#".

The (t) flag is an oddball.  If combined with (P) [rule 4], it takes
effect after that name replacement.  However, if *not* combined with
(P), then it takes effect *before* subscripting [rule 3].  Thus:

    % x=path
    % print ${(t)x}
    scalar
    % print ${x[2,4]}
    ath
    % print ${(t)x[2,4]}
    cal
    % print ${(tP)x}
    array-unique-special

I might have expected ${(t)x[2,4]} to print the type of the variable
named "ath", but that isn't what happens.  So I haven't attempted to
work it into the rules, but it's a perfect example of how parameter
expansion syntax lacks well-defined precedence.


Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.148
diff -u -r1.148 expn.yo
--- Doc/Zsh/expn.yo     19 Oct 2012 09:19:08 -0000      1.148
+++ Doc/Zsh/expn.yo     2 Jan 2013 04:57:04 -0000
@@ -748,6 +748,8 @@
 the length in characters of the result instead of
 the result itself.  If var(spec) is an array expression,
 substitute the number of elements of the result.
+This has the side-effect that joining is skipped even in quoted
+forms, which may affect other sub-expressions in var(spec).
 Note that `tt(^)', `tt(=)', and `tt(~)', below, must appear
 to the left of `tt(#)' when these forms are combined.
 )
@@ -870,11 +872,12 @@
 Create an array parameter with `tt(${)...tt(=)...tt(})',
 `tt(${)...tt(:=)...tt(})' or `tt(${)...tt(::=)...tt(})'.
 If this flag is repeated (as in `tt(AA)'), create an associative
-array parameter.  Assignment is made before sorting or padding.
-The var(name) part may be a subscripted range for ordinary
-arrays; the var(word) part em(must) be converted to an array, for
-example by using `tt(${(AA)=)var(name)tt(=)...tt(})' to activate
-field splitting, when creating an associative array.
+array parameter.  Assignment is made before sorting or padding;
+if field splitting is active, the var(word) part is split before
+assignment.  The var(name) part may be a subscripted range for
+ordinary arrays; the var(word) part em(must) be converted to
+an array, for example by using `tt(${(AA)=)var(name)tt(=)...tt(})'
+to activate field splitting, when creating an associative array.
 )
 item(tt(a))(
 Sort in array index order; when combined with `tt(O)' sort in reverse
@@ -884,7 +887,9 @@
 )
 item(tt(c))(
 With tt(${#)var(name)tt(}), count the total number of characters in an array,
-as if the elements were concatenated with spaces between them.
+as if the elements were concatenated with spaces between them.  This is not
+a true join of the array, so other expressions used with this flag may have
+an effect on the elements of the array before it is counted.
 )
 item(tt(C))(
 Capitalize the resulting words.  `Words' in this case refers to sequences
@@ -1308,7 +1313,8 @@
 subscript.  Thus if tt(var) is an array, tt(${var[1][2]}) is the second
 character of the first word, but tt(${var[2,4][2]}) is the entire third
 word (the second word of the range of words two through four of the
-original array).  Any number of subscripts may appear.
+original array).  Any number of subscripts may appear.  Flags such as
+tt((k)) and tt((v)) which alter the result of subscripting are applied.
 )
 item(tt(4.) em(Parameter name replacement))(
 The effect of any tt((P)) flag, which treats the value so far as a
@@ -1316,11 +1322,12 @@
 )
 item(tt(5.) em(Double-quoted joining))(
 If the value after this process is an array, and the substitution
-appears in double quotes, and no tt((@)) flag is present at the current
-level, the words of the value are joined with the first character of the
-parameter tt($IFS), by default a space, between each word (single word
-arrays are not modified).  If the tt((j)) flag is present, that is used for
-joining instead of tt($IFS).
+appears in double quotes, and neither an tt((@)) flag nor a tt(#)
+length operator is present at the current level, then words of the
+value are joined with the first character of the parameter tt($IFS),
+by default a space, between each word (single word arrays are not
+modified).  If the tt((j)) flag is present, that is used for joining
+instead of tt($IFS).
 )
 item(tt(6.) em(Nested subscripting))(
 Any remaining subscripts (i.e. of a nested substitution) are evaluated at


  reply	other threads:[~2013-01-02  5:15 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-30  9:44 Creating A Clean Environment For Autoloaded Functions Russell Harmon
2012-12-30 19:20 ` Bart Schaefer
2012-12-30 21:02   ` Russell Harmon
2012-12-30 22:12     ` Bart Schaefer
2012-12-31 23:30   ` Han Pingtian
2013-01-02  5:15     ` Bart Schaefer [this message]
2013-01-02  8:32       ` PATCH and more remarks on parameter expansion docs Han Pingtian
2013-01-02 16:46         ` Bart Schaefer
2013-01-02 23:28           ` Han Pingtian
2013-01-03 19:42             ` Bart Schaefer
2013-01-03 22:18               ` Han Pingtian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=130101211501.ZM3814@torch.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-users@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).