--- name: Grouping and counts --- # Grouping and counts **By the end of this chapter you will be able to** repeat a pattern of directives across a list of values, use the `*` and `[…]` forms of repeat count, and write self-describing length-prefixed records with the `/` directive. A bare repeat count applies to *one* directive letter: `C4` packs four bytes. The moment the repeating unit is more than one directive — "pack a short and two bytes, many times" — you need a group. ## `()` — a group is a sub-template Parentheses gather a sequence of directives so that a repeat count or endianness modifier applies to the whole. Compare: ```perl pack "C S C S C S", @a, @b, @c, @d, @e, @f # repeat by hand pack "(CS)3", @a, @b, @c, @d, @e, @f # same thing, grouped pack "(CS)*", @pairs # repeat as often as values last ``` A group has no byte cost of its own — it is a syntactic device. The total packed length is what the directives inside it would produce without the parentheses. ### Grouping with endianness The single most practical use of a group — a sub-structure whose every integer shares one byte order: ```perl my $rec = pack "(l s s)<", $id, $x, $y; # same as "l "example.com", PORT => "443", USER => "alice" ); my $blob = pack "S (S/A* S/A*)*", scalar keys %env, %env; ``` Reading it back: ```perl my %parsed = unpack "S/(S/A* S/A*)", $blob; ``` The pack template says: "one 16-bit count (of pairs), then repeat the sub-template `S/A* S/A*` for each pair." The unpack template reads the count and applies it to the group directly — the count is no longer in the output list. ## Edge cases and constraints - **`/` makes no sense with a fixed-length item.** The second directive must be variable-width: `a*`, `A*`, `Z*`, `/A$n`, or the like. Perl will reject a fixed-length second item. - **`()*` with `pack` cannot be matched by `()*` on unpack.** Pack has the values, so it can say "repeat until done". Unpack does not know how many repetitions are encoded in the buffer unless a count directive precedes the group. - **Nested groups** are legitimate and common: ```perl pack "((CC)(S))<", @records ``` Endianness modifiers cascade through every nesting level. - **Repeat count on a group** applies to the whole group and takes that many repetitions' worth of values. `(CS)3` consumes *six* list values, not three. Next chapter: the directives that move around inside a template without producing a value — `x`, `X`, `@`, `.`.