Scenario:

I have 36 directories. Inside those 36 directories are some ten thousand additional directories. Inside each of those sub directories are a set of files. These files are regularly named. They reflect information stored elsewhere on the disk. It is my task to take the data in the sub directories and reflect them in our database.

I've been doing this with a copy of a script that the original planner of this system had used to convert the data to html.

The reason I'm looking to change it is a) I didnt write it, and its difficult to work with and b) its a 300-line-long if/elsif/else "loop." In other words, its basically three opendirs, with the last one goes over every file, compares it to a regular expression, and then modifies a corresponding variable. that variable is then stored in the database.

an example:

/data/sprocket_logs/spacely.200 /data/sprocket_logs/cogswell.100 /data/cog_logs/cogswell.1000 /data/cog_logs/astro.1
we could interpret this to mean that spacely has 200 sprockets, and that cogswell has 100 sprockets and 1000 cogs, while astro has 1 cog. However, this is not the only kind of information stored in these directories. for example we might see:
/data/cog_logs/maimed_a_robot
indicating that at one point a cog was responsible for a robot maiming. now I know what all these files are going to look like, and have a regular expression for the particular parsing of each of them. however, this if/elsif/else construct is irritating the heck out of me. It is not the right way to do this.

However, when i started coming up with a solution that was more comprehensive, I came up with this:

my %dispatcher => ( \$quux => [ sub { return 0 unless $_[0] =~ ${$_[1]}; ${$_[3]} =~ s/${$_[1]}/${$_[2]}/; return $_[3]; }, qr{bar}, qq{foo}, ], ); $dispatcher{$key} -> [0] -> ($file, $dispatcher{$key} -> [0] -> [1], $dispatcher{$key} -> [0 +] -> [1]);
What this basically does is, (and note the syntax may be off, it's not yet gone past perl -c) is there is a hash with the variables i want to change. each variable has a corresponding listref value which contains the sub that actually changes its value, and the pattern it needs to match for the change to occur, and what to change it to. so, i think its actually even a little elegant. however, it takes up more space and is less maintainable than the "dreaded" if-elsif-else construct.

There has to be a better way than three hundred lines of if statements.

What have you all done when faced with this situation?

thanks,
brother dep.

--
Laziness, Impatience, Hubris, and Generosity.


In reply to The dreaded if-elsif-else construct (code) by deprecated

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.