如何在 Perl 中使用 Getopt::Long 验证读取了哪些标志?

发布于 2024-09-17 23:58:10 字数 635 浏览 8 评论 0原文

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=文件名
    

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

  • 为此,我需要知道 GetOptions 是否将某些内容读入 $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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

↘紸啶 2024-09-24 23:58:10

最简单的解决方案是在 $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";

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";
三生路 2024-09-24 23:58:10
if (defined $f1) {
  # You got a -a option
}

但我个人更喜欢 将选项读入哈希,然后使用exists()。

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

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

梦幻之岛 2024-09-24 23:58:10
$f1 = "$f1.log" unless $f1 =~ m/\.log$/i;

如果文件名尚无扩展名,则附加 log 扩展名。由于默认值以 log 结尾,因此不会发生任何情况。如果用户在命令行上输入log,它就会起作用。

$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.

习惯成性 2024-09-24 23:58:10

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

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文