Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

A Refactoring We Will Go

by hacker (Priest)
on Jun 29, 2003 at 16:03 UTC ( [id://269996]=perlquestion: print w/replies, xml ) Need Help??

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

I've got a script that is part of a larger collection of "tools" I use on a cron'ly basis for mirroring and administration of some distributed servers in a cluster, and it basically wraps a system binary which takes roughly 40 possible arguments.

What I've got thus far, is modified via an email sent to a specific (secured) account on an internal control box. In this email body is a template, pseudo-XML, which contains the options I want to pass to the system binary in 'key = value' pairs, and looks like this:

<tmpl> foo = 1 bar = SomeThing blort = 2003-06-29 </tmpl>

I detach this template from the body of the email with Mail::Internet as follows:

my $message = new Mail::Internet ([<>]); my @body = @{$message->body()};

From here, I parse it out with Config::General, and end up with things like this:

my %config = $conf->getall; my $template = $conf->obj('tmpl'); my $foo = $config{'tmpl'}->{'foo'}; my $bar = $config{'tmpl'}->{'bar'}; my $blort = $config{'tmpl'}->{'blort'}; # ... up to 40 possible values

When I have these all in scalars, I go through them one-by-one, and validate each, to make sure I didn't pass any typos or other invalid values. for example, the key 'foo' in the template can only take a digit, so I can restrict that, and check it. The next key, 'bar' may only take a common word, starting with a capital letter. I can also check that. You can see how lengthy this gets after 40 possible values need to be stuffed into scalars and checked for proper syntax and validity.

Is there a better way to parse, accept, and validate each of these values from the template, without duplicating 40 separate checks for each value that can be passed?

Replies are listed 'Best First'.
Re: A Refactoring We Will Go
by adrianh (Chancellor) on Jun 29, 2003 at 19:48 UTC

    You'll probably find yourself building some kind of Parameter Object class(es).

    I tend to build these with Params::Validate, although Ovid suggested a specific Sub::ParamObject module.

    I'd start by building a single class for all the parameters then, if appropriate, refactor them into separate classes if the parameters show natural groupings (all the Foo related parameters in one class, all the Bar related parameters in another, etc.)

Re: A Refactoring We Will Go
by tcf22 (Priest) on Jun 29, 2003 at 17:25 UTC
    CGI::Validate could be some help on validating the data. You can require that the data be a number, string, email etc. or define your own validation routine.
      He didn't say it was a CGI. In fact, I'm sure it isn't, hacker said it's email-driven, so CGI::Validate is right out.
Re: A Refactoring We Will Go
by hacker (Priest) on Jul 01, 2003 at 15:05 UTC
    Params::Check looks like it is the right module for use here, and I managed to get it working, somewhat (with a slight syntax poke/help from jeffa). Now the problem is that I need to generate a custom error message when the params are incorrect (instead of the generic die "Could not parse arguments\n"; message).

    For example, if I accept a date range in 'blort' above ($conf{'template'}->{'blort'}) of the format YYYY-MM-DD, and the value supplied by the template's value in that key is DD-MM-YYYY, I would like to die with an error specific to that key, and then return a list of the proper syntax, such as:

    "Date format incorrect, please supply the date in the format YYYY-MM-DD for proper parsing."

    How would I go about doing that? I see that in Params::Check, I can run another sub inside the accept() object to pass the args, and validate that way, but now I'm back to doing ~40 different calls to that check, which is back to where I started.

      I'd patch the module to support a custom message per parameter.

                      - tye

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://269996]
Approved by Tomte
Front-paged by hsmyers
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (2)
As of 2024-04-20 04:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found