If you are given just filenames on the command line, you can simply use <> and Perl will read them for you. That will also work if you get your input from STDIN, so it's the most flexible way of handling things - and it's less code for you to write too.

Here's one stab at cleaning this up:

#!/usr/bin/perl -w use strict; #%GROUP ALSMS_consolidation #%CHPTR ALSMS_consolidation #%SBCH1 WORK_switch_id print "group ^ chapter ^ name ^ description\n"; my (%outer, $group, $chapter); while(<>) { chomp; @line = split /\s+/; if(/^\%SBCH1/) { my ($key, $value); print "$key: ", join(", ", @$value), "\n\n" while ($key, $value) = each %outer %outer=(); } elsif(/^\%GROUP/) { $group = $line[1]; } elsif(/^\%CHPTR/) { $chapter = $line[1]; } elsif(/^\%/) { push @{$outer{$line[0]}}, join ' ', @line[1 .. $#line]; } }
At this point I'd move all the cases into an hash and let the regex engine pick out the right one for me. The array formerly stored in @line is now passed through the parameter list. I put these all into an array first because the order of keys is important for the regex built from it.
#!/usr/bin/perl -w use strict; #%GROUP ALSMS_consolidation #%CHPTR ALSMS_consolidation #%SBCH1 WORK_switch_id my (%outer, $group, $chapter); my @handler = ( SBCH1 => sub { my ($key, $value); print "$key: ", join(", ", @$value), "\n\n" while ($key, $value) = each %outer %outer=(); }, GROUP => sub { $group = $_[1] }, CHPTR => sub { $chapter = $_[1] }, "" => sub { push @{$outer{$_[0]}}, join ' ', @_[1 .. $#line] }, ); my %handler = @handler; my $rx = do { my @key; while(@handler) { # take two element from front, throw away the second my ($key) = splice @handler, 0, 2; push @key, $key; } join '|', @key; }; $rx = qr/^\%($rx)/; print "group ^ chapter ^ name ^ description\n"; while(<>) { if(/$rx/) { chomp; $handler{$1}->(split /\s+/); } }

Note that now, the loop doesn't chomp and split the string unless it actually found a handled tag at the front of the string - it's always good not to do any more work than necessary.

It does look more complicated now - and indeed, if you really, really won't ever need any more than you originally had, it may not even be worth it. But if you ever have to extend your code, it is quite helpful to work with hashes of subroutines rather than use huge if/elsif blocks.

Makeshifts last the longest.


In reply to Re^3: push to a hash of arrays by Aristotle
in thread push to a hash of arrays by aennen

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.