In my program, the user may enter various types of information (integer, numeric, dates, time, strings, IP addresses, etc.). The program reads from a configuration file what type of information is needed, and then verifies that the user entered the correct type of value.

Originally, I had a series of if/elsif statements to check the type of entry against a particular subroutine. Something like this:

if ($type == "INTEGER") { $convAnswer = checkInteger($answer); } elsif ($type eq "DATE") { $convAnswer = checkDate($answer); } elsif ($type eq "IPADDRESS") { $convAnswer = checkIpaddress($answer); } elsif ($type eq "FOO") { $convAnswer = checkFoo($answer); } else { die qq(There is no such type as "$type"\n); }
This worked, but it created really long bits of code. Plus, if I created a new "type", I would have to go into my code, and change the if/elsif statements. Therefore, I am attempting to switch to this:

my $sub = "check" . ucfirst(lc($type)); if (not defined (&{$sub}) { die qq(There is no such type as "$type"\n); } $convAnswer = &{$sub}($answer);
The good news is that this makes my program easier to maintain and understand because I've eliminated dozens of lines of testing data types and seeing which routine is needed. To add a new variable type, I simply have to define a new routine.

The bad news is that this fails if I have "strict 'refs'" invoked. I could do this:

my $sub = "check" . ucfirst(lc($type)); if (not defined (&{$sub}) { die qq(There is no such type as "$type"\n); } no strict "refs"; $convAnswer = &{$sub}($answer); use strict "refs"
And that works, but I feel there should be a better way without turning off strict "refs".

Is there a better way of doing this? I was thinking of putting the check inside an eval block and then seeing if the eval succeeds or fails. However, I think this makes the code even more difficult to understand, so I would prefer to be able to use subroutine references if possible.


In reply to Trying to get around the "use strict 'refs'" Issue by qazwart

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.