Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^2: Modifying pos() from within (?{...})

by mxb (Pilgrim)
on Apr 26, 2018 at 14:23 UTC ( [id://1213611]=note: print w/replies, xml ) Need Help??


in reply to Re: Modifying pos() from within (?{...})
in thread Modifying pos() from within (?{...})

Thanks for your help also!

But using unpack is better for, ahem, unpacking binary formats. You could write something like:

my ($tag, $data, $crc) = unpack q( (x4L X8Lx4/a* L)> ), $input;

Place ( )* around the template to get all the chunks.

Wow, that's concise and reasonably clear. I'm learning regex and more advanced pack|unpack at the same time so it's definitely something I need to dig into deeper.

Armed with the pack documentation I dissected your pack string into the following:

x4 - four null bytes (effectively skip the length fields)

L - 32bit value (the tag)

X8 - seek backwards 8 bytes (back to the start of the chunk

L - 32bit value (data length)

x4 - four null bytes (skip the tag field)

/ - pops the last value (data length) off the extraction stack and uses it as a repetition count for the next item

a* - binary data (count is set by the / above); not sure why * follows it, it works when removed

L - 32 bit CRC

It seems that I need to go through perlpacktut next!

I do have a small question however, when I try to repeat the group with * I get the following error:

'x' outside of string in unpack

Maybe this is something to do with the x at the start of the group? It's trying to read a new group starting just past the end of the string?

edit:Changing the first part of the pack string to L seemed to fix the 'outside of string' error. The data length is now explicitly within the returned values, but could be ignored later.

edit2:I span this out into a separate thread as it was getting too far off the original topic.

Replies are listed 'Best First'.
Re^3: Modifying pos() from within (?{...})
by Eily (Monsignor) on Apr 27, 2018 at 15:10 UTC

    I already answered in the second thread, that the $input has an extra \n at the end, and I just realized why. The funny thing is, I reached that conclusion for the wrong reason. When I did my test I didn't modify $/ and didn't call chomp, so the \n wasn't removed. You, on the other hand did have chomp, but with $/ set to undef. The chomp doc states:

    When in slurp mode ($/ = undef ) or fixed-length record mode ($/ is a reference to an integer or the like; see perlvar), chomp won't remove anything.

    So in my tests by forgetting to call chomp, I got the same result you had by disabling its effect, and therefore reached the correct conclusion :D

      When in slurp mode ... chomp won't remove anything.

      Another illustration of the wisdom of local-ized modification of globals in the narrowest scope, e.g.
          my $input = do { local $/;  <DATA>; };
      rather than in broad or, indeed, global scope even when "it's just a small program; it doesn't really matter what we do to globals": spooky action at a distance.


      Give a man a fish:  <%-{-{-{-<

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1213611]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2024-04-24 07:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found