mhearse has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to shorten/simplify this huge loop. As you can see, there is repeated calls to the check sub routine. A different hash reference is passed depending on what is detected at the beginning of each line in the file. I'm new to 00, so I'm not sure if it would work here. Maybe there is a better way to write things in general. I'm open to any suggestions.
while (<>) { chomp; s/ //g; tr/a-z/A-Z/; if (/^APG/) { @APG = split /,"?|""?/; check (\%APGF); } elsif (/^CBR/) { @CBR = split /,"?|""?/; check (\%CBRF); } elsif (/^CLR/) { @CLR = split /,"?|""?/; check (\%CLRF); } elsif (/^CNY/) { @CNY = split /,"?|""?/; check (\%CNYF); } elsif (/^COD/) { @COD = split /,"?|""?/; check (\%CODF); } elsif (/^CWF/) { @CWF = split /,"?|""?/; check (\%CWF); } elsif (/^DSR/) { @DSR = split /,"?|""?/; check (\%DSRF); } elsif (/^ENH/) { @ENH = split /,"?|""?/; check (\%ENHF); } elsif (/^GEO/) { @GEO = split /,"?|""?/; check (\%GEOF); } elsif (/^GRD/) { @GRD = split /,"?|""?/; check (\%GRDF); } elsif (/^HOD/) { @HOD = split /,"?|""?/; check (\%HODF); } elsif (/^HUR/) { @HUR = split /,"?|""?/; check (\%HURF); } elsif (/^IFL/) { @IFL = split /,"?|""?/; check (\%IFL); } elsif (/^IFR/) { @IFR = split /,"?|""?/; check (\%IFRF); } elsif (/^IMG/) { @IMG = split /,"?|""?/; check (\%IMGF); } elsif (/^IMP/) { @IMP = split /,"?|""?/; check (\%IMPG); } elsif (/^ISE/) { @ISE = split /,"?|""?/; check (\%ISEF); } elsif (/^ISF/) { @ISF = split /,"?|""?/; check (\%ISFF); } elsif (/^ISO/) { @ISO = split /,"?|""?/; check (\%ISOF); } elsif (/^ISR/) { @ISR = split /,"?|""?/; check (\%ISRF); } elsif (/^LAB/) { @LAB = split /,"?|""?/; check (\%LABF); } elsif (/^LAN/) { @LAN = split /,"?|""?/; check (\%LANF); } elsif (/^LEG/) { @LEG = split /,"?|""?/; check (\%LEG); } elsif (/^LIT/) { @LIT = split /,"?|","|"/; check (\%LITF); } elsif (/^LPR/) { @LPR = split /,"?|""?/; check (\%LPRF); } elsif (/^LTL/) { @LTL = aplit /,"?|""?/; check (\%LTLF); } elsif (/^MAP/) { @MAP = aplit /,"?|""?/; check (\%MAPF); } elsif (/^MCC/) { @MCC = split /,"?|""?/; check (\%MCCF); } elsif (/^MEI/) { @MEI = split /,"?|""?/; check (\%MEIF); } elsif (/^MMM/) { @MMM = split /,"?|""?/; check (\%MMMF); } elsif (/^MFR/) { @MFR = split /,"?|""?/; check (\%MFRF); } elsif (/^MPB/) { @MPB = split /,"?|""?/; check (\%MPBF); } elsif (/^MPF/) { @MPF = split /,"?|""?/; check (\%MPFF); } elsif (/^MRQ/) { @MRQ = split /,"?|""?/; check (\%MRQF); } elsif (/^OVR/) { @OVR = split /,"?|""?/; check (\%OVRF); } elsif (/^PIR/) { @PIR = aplit /,"?|""?/; check (\%PIRF); } elsif (/^PRC/) { @PRC = split /,"?|""?/; check (\%PRCF); } elsif (/^RET/) { @RET = split /,"?|""?/; check (\%RETF); } elsif (/^RHP/) { @RHP = split /,"?|""?/; check (\%RHPF); } elsif (/^SEN/) { @SEN = split /,"?|""?/; check (\%SENF); } elsif (/^SGW/) { @SGW = split /,"?|""?/; check (\%SGWF); } elsif (/^SHP/) { @SHP = split /,"?|""?/; check (\%SHPF); } elsif (/^SKT/) { @SKT = split /,"?|""?/; check (\%SKTF); } elsif (/^SLG/) { @SLG = split /,"?|""?/; check (\%SLGF); } elsif (/^SLP/) { @SLP = split /,"?|""?/; check (\%SLPF); } elsif (/^SPC/) { @SPC = split /,"?|""?/; check (\%SPCF); } elsif (/^STP/) { @STP = split /,"?|""?/; check (\%STPF); } elsif (/^STR/) { @STR = split /,"?|""?/; check (\%STRF); } elsif (/^STV/) { @STV = split /,"?|""?/; check (\%STVF); } elsif (/^SVR/) { @SVR = split /,"?|""?/; check (\%SVRF); } elsif (/^SWO/) { @SWO = split /,"?|""?/; check (\%SWOF); } elsif (/^SYM/) { @SYM = split /,"?|""?/; check (\%SYMF); } elsif (/^WWA/) { @WWA = split /,"?|""?/; check (\%WWAF); } elsif (/^XSM/) { @XSM = split /,"?|""?/; check (\%XSMF); } elsif (/^XSN/) { @XSN = split /,"?|""?/; check (\%XSNF); } elsif (/^\s*$/) { next; } elsif (/^\*/) { next; } else { s/\W.*//; chomp $_; warn "$ARGV ling $.: \"$_\" is not a valid APG command!\n"; } close ARGV if eof; }

update (broquaint): added <readmore> tag

Replies are listed 'Best First'.
Re: Shorten/simplify repetitive code
by Abigail-II (Bishop) on Oct 15, 2003 at 16:10 UTC
    #!/usr/bin/perl use strict; use warnings; my %prefixes = map {$_ => 1} qw /APG CBR CLR CNY COD .../; my %array; # Holds @APG, @CBR, @CLR, etc. my %hash; # Holds %APGF, %CBRF, %CLRF, etc. while (<>) { chomp; s/ +//g; # Use of '+' is faster if there are consecutive spac +es. tr/a-z/A-Z/; # Or $_ = uc; if (/^(\w{3})/ && $prefixes {$1}) { my $name = $1; @{$array {$name}} = split /,"?|""?/; check $hash {"${name}F"}; # Is already a reference. } else { s/\W.*//; warn qq {$ARGV line $.: "$_" is not a valid APG command!\n"}; } }

    Abigail

•Re: Shorten/simplify repetitive code
by merlyn (Sage) on Oct 15, 2003 at 15:53 UTC
    Treating many variables similarly is a good sign that they belong as part of a larger data structure. Consider a hash containing arrayrefs for what you had formerly put in separate arrays.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.