Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Unpack Many Fields

by BrowserUk (Patriarch)
on Feb 15, 2010 at 23:53 UTC ( [id://823372]=note: print w/replies, xml ) Need Help??


in reply to Unpack Many Fields

If you only need 34 of 170 fields, you can use x[nnn] to skip the bytes between the fields you want. That should reduce the unweildy length of your template considerably.

And if the template is still uncomfortably long:

my $fmt = join '', qw[ x[10] a5 x[22] a10 x[4] a3 a2 ... ];

You can even turn that into an opportunity to document:

my $fmt = join '', grep !m[^#], qw[ x[10] a5 #code x[22] a10 #thingummy x[4] a3 a2 #doodah&whatsit ... ];

As for the naming of the fields, rather than using strings of "FIELDnn" in a hash, why not use an array?

Eg.

my $fmt = "x[10]a5x[22]a10x[4]a3a2..."; my %hash; while( <$fh> ) { my( $code, @fields ) = unpack $fmt, $line; $hash->{$code} = \@fields; } ... for my $code ( keys %hash ) { print $hash->{ $code }[ $_ ] for 0 .. 33; }

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Unpack Many Fields
by ikegami (Patriarch) on Feb 16, 2010 at 01:53 UTC
    Using # in qw causes a warning. The following removes warnings and allows spaces to be used in the comment:
    my $fmt = q[ x[10] a5 # code x[22] a10 # thingummy x[4] a3 a2 # doodah & whatsit ]; $fmt =~ s/#.*//g;

    But pack allows for comments in patterns, so one doesn't even need that last line.

    Update: Originally, the /g was missing, which led me to discover that one doesn't need to remove the comments.

      I think it has to be something like
      $fmt =~ s/(?:#.*)|\n|\s//g;
      Thanks to both of you!
      My code is already looking much better.
      Cheers!

        Not at all. For starters,

        s/(?:#.*)|\n|\s//g

        is the same as

        s/#.*|\s//g

        Secondly, spaces are allowed in the pattern, so your change is unwarranted.

        Finally, comments are allowed in the pattern, so you don't need the substitution at all.

      Whaddayaknow! That definitely deserves a mench in perlfunc.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        It does. The first sentence of the following is present since at least 5.6.0:

        A comment in a TEMPLATE starts with # and goes to the end of line. White space may be used to separate pack codes from each other, but modifiers and a repeat count must follow immediately.

        It would be nice if WS and # were mentioned in the table at the top, though.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (7)
As of 2024-04-16 12:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found