开发者

How to verify which flags were read using Getopt::Long in Perl?

开发者 https://www.devze.com 2023-01-15 17:03 出处:网络
myscript.pl my $R; my $f1 = \"f1.log\"; my $f2 = \"f2.log\"; my $f3 = \"f3.log\"; sub checkflags { GetOptions(\'a=s\'=> \\$f1,

myscript.pl

my $R;
my $f1 = "f1.log";
my $f2 = "f2.log";
my $f3 = "f3.log";

sub checkflags {

    GetOptions('a=s'    => \$f1,
               'b=s'    => \$f2,
               'c=s'    => \$f3,
    );

    open $R, '>', $f1 or die "Cannot open file\n"; # Line a
}
  • All开发者_Go百科 the flags are optional.

  • If I call the script as

    perl myscript.pl -a=filename
    

    I need to append a .log to the filename before opening it at Line a.

  • For that I need to know whether GetOptions read something into $f1 or not.

How can this be done?


The simplest solution is to look for /[.]log$/ in $f1 and add it if it isn't present. Unfortunately that means that when the user passes in "foo.log" and wanted it to become "foo.log.log" it won't, but I think we can agree that user is a jerk.

A better option, that will make the jerk happy, is:

#!/usr/bin/perl

use strict;
use warnings;

use Getopt::Long;

GetOptions(
    'a=s'    => \my $f1,
    'b=s'    => \my $f2,
    'c=s'    => \my $f3,
);

if (defined $f1) {
    $f1 .= ".log";
} else {
    $f1 = "f1.log";
}

print "$f1\n";

If you want to define all of default names at the top, use a different variable to do that (it is probably better reading code anyway):

#!/usr/bin/perl

use strict;
use warnings;

use Getopt::Long;

my $default_f1 = "f1.log";
my $default_f2 = "f2.log";
my $default_f3 = "f3.log";

GetOptions(
    'a=s'    => \my $f1,
    'b=s'    => \my $f2,
    'c=s'    => \my $f3,
);

if (defined $f1) {
    $f1 .= ".log";
} else {
    $f1 = $default_f1;
}

print "$f1\n";


if (defined $f1) {
  # You got a -a option
}

But personally I'd prefer to read the options into a hash and then use exists().


$f1 = "$f1.log" unless $f1 =~ m/\.log$/i;

Appends the log extension if the file name does not already have one. Since the default value ends in log, nothing happens. And it works if the user types the log on the command line.


One way to achieve this is to use Moose and MooseX::Getopt:

package MyApp;

use strict;
use warnings;

use Moose;
with 'MooseX::Getopt';

has f1 => (
    is => 'ro', isa => 'Str',
    cmd_aliases => 'a',
    default => 'f1.log',
    predicate => 'has_a',
);
has f2 => (
    is => 'ro', isa => 'Str',
    cmd_aliases => 'b',
    default => 'f2.log',
    predicate => 'has_b',
);
has f3 => (
    is => 'ro', isa => 'Str',
    cmd_aliases => 'c',
    default => 'f3.log',
    predicate => 'has_c',
);

# this is run immediately after construction
sub BUILD
{
    my $this = shift;

    print "a was provided\n" if $this->has_a;
    print "b was provided\n" if $this->has_b;
    print "c was provided\n" if $this->has_c;
}

1;
0

精彩评论

暂无评论...
验证码 换一张
取 消