in reply to Re^3: Reading binary files - program structure
in thread Reading binary files - program structure

Thanks for all the suggestions - now posting an update for anyone who stumbles on this.

I started with something like almut's state machine but didn't like the way the structure of the file I was trying to read is then encoded into the script structure - feels like poor code/data separation.

What I've ended up with is more like BrowserUk's suggestions. The crucial point (which I didn't really realise when I originally posted) was that the file format defines how many words should be read for each "variable" in the file, although in most cases that length is actually defined by algebra involving previously-read variables. So we can do something like this:

my %v; # this hash holds all the data read # define the names of the "variables" to read from the file # *** in the correct order *** my @varnames = qw/this that theother/; # define where the length to read is not a default my %varlengths = ('that' => 2, 'theother' = '$v{this}*2'} foreach my $var (@varnames){ # get the length to read my $readlength; if(! exists($varlengths{$var}) $readlength = 1; # default } else { $readlength = eval($varlengths{$var}); # compute it } # read into %v if ($readlength == 1){ # read a scalar $v{$var} = unpack TEMPL1, read( $file, $readlength ); } else { # read into an anon. array $v{$var} = [ unpack TEMPL1, read( $file, $readlength ) ]; } }

Replies are listed 'Best First'.
Re^2: Reading binary files - program structure
by BrowserUk (Patriarch) on May 24, 2010 at 20:38 UTC

    I think would prefer to use subs rather than string eval here. Eg.

    my %varlengths = ( 'that' => sub(){ 2 }, 'theother' = sub{ $v{this}*2 }, } ... $readlength = $varlengths{$var}->(); # compute it

    Slightly more work, but worth it I think.


    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.
      Interesting, I didn't even know you could do that! Presumably the advantage is speed? Being a compile-time thing rather than a run-time eval?

      If/when I finally make progress on this I'll compare the approaches.

        Presumably the advantage is speed? Being a compile-time thing rather than a run-time eval?

        That's a beneficial side-effect of avoiding string eval. But mostly just a healthy aversion to using it, if it is easier to avoid it.

        I don't subscribe to the evil-eval notion--if I need to evaluate a runtime mathematical expression, I will. Far easier to use Perl's expression parser than write my own, or discover the limitations of someone else's--but for the usage outlined, everything is known at compile-time, so no need to invoke the compiler again (multiple times) at runtime.


        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.