【问题标题】:How to verify which flags were read using Getopt::Long in Perl?如何验证在 Perl 中使用 Getopt::Long 读取了哪些标志?
【发布时间】:2011-04-09 04:06:23
【问题描述】:

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
}
  • 所有标志都是可选的。

  • 如果我将脚本称为

    perl myscript.pl -a=filename
    

    我需要在文件名上附加一个.log,然后才能在Line a 打开它。

  • 为此,我需要知道GetOptions 是否将某些内容读入$f1

如何做到这一点?

【问题讨论】:

    标签: perl command-line-arguments getopt-long


    【解决方案1】:
    if (defined $f1) {
      # You got a -a option
    }
    

    但我个人更喜欢read the options into a hash,然后使用exists()。

    【讨论】:

    • 由于我在第 2 行的初始化,这将永远是正确的。
    【解决方案2】:

    最简单的解决方案是在$f1 中查找/[.]log$/,如果不存在则添加。不幸的是,这意味着当用户传入"foo.log" 并希望它变成"foo.log.log" 时它不会,但我认为我们可以同意用户是个混蛋。

    让混蛋开心的更好选择是:

    #!/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";
    

    如果您想在顶部定义所有默认名称,请使用不同的变量来执行此操作(无论如何阅读代码可能会更好):

    #!/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";
    

    【讨论】:

    • 如果他们真的想要那个文件名,他们总是可以直接传递foo.log.log
    【解决方案3】:
    $f1 = "$f1.log" unless $f1 =~ m/\.log$/i;
    

    如果文件名还没有扩展名,则附加 log 扩展名。由于默认值以 log 结尾,因此没有任何反应。如果用户在命令行上键入 log,它就会起作用。

    【讨论】:

    • 您能否详细说明使用m/\.log$/i 的追加是如何发生的?
    • 希望日志命名为foo.log.log的用户呢?
    • 追加发生在赋值中:$f1 = "$f1.log".
    【解决方案4】:

    实现此目的的一种方法是使用MooseMooseX::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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多