Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I think your last proposition (first unpacking the count, then generating a template using it) is probably your best option, most readable.

You might be able to achieve what you want with something like the code below, but it really lacks clarity when you want to read something longer than a byte:

use strict; use warnings; use Data::Dump qw( pp ); my $str = pack "C (a)*", 4, 'a'..'z'; pp $str; pp unpack 'C/a @0 CXC/x/a @0 CXCXC/x/x/a', $str;
"\4abcdefghijklmnopqrstuvwxyz" ("abcd", "efgh", "ijkl")

  • You already know what C/a does. => the stack is ("abcd") and pos = 5
  • @0 goes back to the start. => the stack is ("abcd") and pos = 0
  • CXC reads the first value, goes back one byte, and reads it again => the current list is ("abcd", 4, 4) and pos = 1
  • /x removes the last value in the list (4) and uses it as a repeat count for x, which just skips a byte (so /x ignores four bytes) => the list is ("abcd", 4) and pos = 5
  • /a removes the last value in the list (4 again), and uses it as a repeat count for a => the list is ("abcd", "efgh") and pos = 9
  • @0 goes back the start, CXCXC reads the count three times, /x/x uses the count twice to skip bytes, and /a reads the last substring.

This gets harder when you want to skip more than one byte at a time. This can be done with x[V] which means "skip as many bytes as there are in V". But you can't write C/x[V] because the x would have two counts (one explicit, and one from the stack). So you have to write C/(x[V]) where you apply C times the group "skip as many bytes as in V".
However, at least in my version of perl, you can't use: CXC /(x[a]) /a because skipping a group seems to change the stack and add an element that is used instead of the correct value. It kind of looks like after C/a CXC /(x[a]) the stack is actually ("abcd", 4, ()) instead of ("abcd", 4). That extra element is removed if you add "xX" which skips one byte forward, and skips one byte backward. This doesn't do anything useful, except the next /a does what you want.

This leads to : pp unpack 'C/a @0 CXC /(x[a]) xX /a @0 CXC /((x[a])2) xX /a', $str;
Once again, your last proposition is probably a better solution.

In reply to Re: pack and unpack multiple arrays with one common repeat prefix by Eily
in thread pack and unpack multiple arrays with one common repeat prefix by hexcoder

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (1)
As of 2022-05-22 10:07 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (80 votes). Check out past polls.