Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Reduce Redundant Repetition

by ybiC (Prior)
on Jan 21, 2002 at 21:18 UTC ( [id://140434]=perlquestion: print w/replies, xml ) Need Help??

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

The following chunk facilitates default values for command-line arguments.   It works fine, but I suspect there's a less redundant approach than just repeating "if defined($opt_foo){$foo=$opt_foo} else {$foo=def_val}" for seven different values of "foo".   I'd use hash keys and values, but there are three unique parameters for each iteration.

Suggestions, o wise brethren and sistren?

#!/usr/bin/perl -w use strict; use Getopt::Long my ( $targ, $opt_targ, $firstport, $opt_firstport, $lastport, $opt_lastport, $proto, $opt_proto, $udptimeout, $opt_udptimeout, $contimeout, $opt_contimeout, $help, ); GetOptions( 'targ=s' => \$opt_targ, 'firstport=s' => \$opt_firstport, 'lastport=s' => \$opt_lastport, 'proto=s' => \$opt_proto, 'udptimeout=s' => \$opt_udptimeout, 'contimeout=s' => \$opt_contimeout, 'help!' => \$opt_help, ); if (defined $opt_targ){ $targ = $opt_targ } else {$targ='localhost';} if (defined $opt_firstport){ $firstport = $opt_firstport } else {$firstport=1;} if (defined $opt_lastport){ $lastport = $opt_lastport } else {$lastport=1024;} if (defined $opt_proto){ $proto = $opt_proto} else {$proto='tcp';} if (defined $opt_udptimeout){ $udptimeout = $opt_udptimeout } else {$udptimeout=3;} if (defined $opt_contimeout){ $contimeout = $opt_contimeout } else {$contimeout=3;} if (defined $opt_help){ Usage('You rang, sir?'); exit; }

    cheers,
    Don
    striving toward Perl Adept
    (it's pronounced "why-bick")

Replies are listed 'Best First'.
(jcwren) Re: Reduce Redundant Repetition
by jcwren (Prior) on Jan 21, 2002 at 21:21 UTC

    How about:

    $proto = defined $opt_proto ? $opt_proto : 'tcp'

    Personally, though, I'd go for putting all your arguments in a hash, with a reference to the opt_arg value, the variable you want the final result in, and the default value, and use a for loop to rip through them setting them all. Perhaps include a type (numeric, string, flag) and do a little type checking. For instance, if someone passed '123' to the $opt_tcp value, it prolly ain't gonna work...

    --Chris

    e-mail jcwren

Re: Reduce Redundant Repetition
by kal (Hermit) on Jan 21, 2002 at 21:38 UTC

    There are a number of ways to reduce some of this. The easiest way to get rid of the if's is probably something like:

    $contimeout = $opt_contimeout || 3;

    Another simple way of setting defaults is to set them up before using Getopt::Long:

    #!/usr/bin/perl -w use strict; use Getopt::Long; my ($lines, $cols) = (5, 16); GetOptions ('line=s' => \$lines, 'col=s' => \$cols); print "Lines: $lines Cols: $cols\n";

    A very simple example I know, but it illustrates the point :)

    Update: jcwren pointed out that I failed to mention this has a potential failure if you use '||' - if you want to set a value to '0', you won't be able to unless the default is also '0'. I advise pre-setting the defaults, and then letting the user override them - much simpler :) Thanks, jcwren.

(tye)Re: Reduce Redundant Repetition
by tye (Sage) on Jan 21, 2002 at 22:08 UTC
Re: Reduce Redundant Repetition (Rus: use ternaries)
by Russ (Deacon) on Jan 22, 2002 at 00:08 UTC
    I don't see anyone using the ternary operator...
    $targ = defined $opt_targ ? $opt_targ : 'localhost'; $firstport = defined $opt_firstport ? $opt_firstport : 1; $lastport = defined $opt_lastport ? $opt_lastport : 1024; $proto = defined $opt_proto ? $opt_proto : 'tcp'; $udptimeout = defined $opt_udptimeout ? $opt_udptimeout : 3; $contimeout = defined $opt_contimeout ? $opt_contimeout : 3; Usage('<lurch>You rang?</lurch>'), exit if defined $opt_help;
    And it still works with valid zero values.

    Russ

Re: Reduce Redundant Repetition
by mrbbking (Hermit) on Jan 21, 2002 at 23:15 UTC
    You might consider replacing something like this...
    if (defined $opt_targ){ $targ = $opt_targ } else {$targ='localhost';}
    with something like this...
    $targ = $opt_arg; $targ ||= 'localhost';
    ...following the "this breaks if zero is an acceptable value" admonition previously stated above...
Re: Reduce Redundant Repetition
by Aristotle (Chancellor) on Jan 22, 2002 at 03:27 UTC
    A demonstration is better than many words:
    #!/usr/bin/perl -w use strict; use Getopt::Long; my $targ = 'localhost'; my $firstport = 1; my $lastport = 1024; my $proto = 'tcp'; my $udptimeout = 3; my $contimeout = 3; { my %options; GetOptions(\%options, qw(targ=s firstport=s lastport=s proto=s udpti +meout=s contimeout=s help!)); if (defined $options{help}){ Usage('You rang, sir?'); exit; } ($targ, $firstport, $lastport, $proto, $udptimeout, $contimeout) = @options{qw(targ firstport lastport proto udptimeout contimeout)}; }

    With some further generalization the variable-/option-names wouldn't have to appear four times each as in this code either.

    Update: maybe you want qw(targ=s firstport=s lastport=s proto=s udptimeout=i contimeout=i help!)? I can see someone saying POP3 for the port f.ex - but it doesn't seem to make any sense to take arbitrary values for the timeout parameters.

    Makeshifts last the longest.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (5)
As of 2024-04-20 00:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found