http://qs321.pair.com?node_id=1181371


in reply to Behaviour of unpack() with the Z template

I think perl is simply trying to be "symmetric" in packing/unpacking. When packing, "Z" adds NUL to original data. Out of symmetry, when unpacking "Z" should remove that added NUL. The documentation is not clear about this aspect. So I would suggest to understand it as

When unpacking, A strips trailing whitespace and nulls, Z strips everything from the first null to the end, and a returns data with no stripping at all.
Maybe some day, someone will actually update the docs :) Or change the behavior of "Z*" to get data to first NUL only, which would allow stuff like
$b = pack("Z*C", "test", 10) ($str, $byte) = unpack("Z*C", $b);
Though changing of docs is more likely :)

EDIT. I'm wrong. In fact the "Z*" already takes the data to the first NUL and does not grab the rest. So, the above example actually works. But the documentation is completely incorrect. It should read

When unpacking, a grabs everything and returns unchanged, A grabs everything but strips from first null to the end and trailing spaces. Z stops after first null, the null is stripped from data.

and a returns everything with no stripping at all.

Replies are listed 'Best First'.
Re^2: Behaviour of unpack() with the Z template
by johngg (Canon) on Feb 08, 2017 at 10:45 UTC

    I agree that the actual behaviour is "symmetric" and that makes sense from a design point of view. I confirmed the behaviour of the test you ran

    johngg@shiraz:~/perl > perl -Mstrict -Mwarnings -E ' my $pck = pack q{Z*C}, q{test}, 0x41; my( $str, $ch ) = unpack q{Z*a}, $pck; say qq{$str, $ch};' test, A

    I don't think the documentation has a problem with the "A" or "a" descriptions but the "Z" one should be clarified. An alternative to my suggestion in the above might be Z returns everything up to but not including the first null.

    Cheers,

    JohnGG

      Yes, you right, looks like I've done tests for "A*" incorrectly.