develooper Front page | perl.perl5.porters | Postings from May 2004

Re: RFC: proposed extension of unpack

Thread Previous
LAUN Wolfgang
May 24, 2004 03:24
Re: RFC: proposed extension of unpack
Message ID:
At # Fri, 21 May 2004 15:23:09 +0000 (UTC) Ton Hospel wrote:
> On perlmonks I just noticed
>, which indeed seems
> you can't currently do with plain unpack and seems useful.
> So i thought it would be nice to have:
> "return current absolute position counted from the start of the string"
> At first look I thought that @ would be nice for this, but it already
> does something useful, namely moving to a given position and continue
> unpacking there.
> However, it's actually not documented what it does if you don't give it
> a numeric argument (the section on repeat counts defines the @ behaviour
> only for n and *). In that case it seems to go to fixed offset 1
> (1 being the logical default for the repeaters of course), which doesn't
> seem particularly useful and can easily be done by using @1, and
> probably *IS* done that way by all existing code, so it would probably
> break no existing code to make @ without followup number in unpack
> return a position (and if something does break, well, they were using
> an undocumented feature...)

The general implication that 1 is to be assumed whenever there is no
explicit length/repeat count cannot be exactly called an "undocumented

I'm very much against the notion of assigning opposing semantics (i.e.
"goto offset" vs. "gimme offset") to code C<@> depending on the presence
or absence of the count.

> The returned offset would be relative to the innermost () to keep it
> consistent. You probably wouldn't want to use an absolute position
> modifier inside a () anyways, so it doesn't really seem to lose
> anything.
> Opinions ?

The original perlmonks example is

  $t = unpack('C', $foo);
  if    ($t == 0) { $v = unpack('C',  substr($foo, 1)) }
  elsif ($t == 1) { $v = unpack('S',  substr($foo, 1)) }
  elsif ($t == 2) { $v = unpack('L',  substr($foo, 1)) }
  elsif ($t == 3) { $v = unpack('Z*', substr($foo, 1)) }

the question being where in $foo to continue in case $t == 3. Now I'd
write that

  ( $t, $foo ) = unpack( 'C A*', $foo );
  ( $v, $foo ) = unpack( qw( C S L Z* )[$t] . 'A*', $foo );

and now $foo is the remainder of the original string, irrespective of
how $v is packed. The proposed function wouldn't bring much of
an improvement.


Thread Previous Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About