可以在2个软件包中使用Perl的Getopt :: Std吗?

时间:2017-06-08 11:12:41

标签: perl getopt

[perl脚本] perl_script.pl -b" HELLO" -v

use package1;
use package2;

my $argb = GetPackage1Option;
my $argv = GetPackage2Option;

print "$argb\n";                                # Print -b argument
print "v is found!\n" if ( GetPackage2Option ); # Print

[package1.pm]

use Getopt::Std;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw( GetPackage1Option );

sub GetPackage1Option {

    getopt('b');
    our ($opt_b);

    my $argb = $opt_b || '';

    return $argb;
}

[package2.pm]

use Getopt::Std;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw( GetPackage2Option );

sub GetPackage2Option {

    my $bool = 0;
    my %opt;
    getopts('v', \%opt);

    return ( defined $optHash{v} ) ? $optHash{v} : $bool;
}

我从2个独立的包调用2个函数,每个函数使用不同的选项。

我试过这个,但我只得到-b的选项。如果我删除使用-b。

的函数,则-v选项有效

道歉这只是我原始代码的摘要。

如果我的问题令人困惑,请告诉我。谢谢:))

2 个答案:

答案 0 :(得分:2)

Getopt::Std操作并“消耗”全局@ARGV数组。要多次运行getoptgetopts,您可以使用local制作@ARGV的临时副本。

sub GetPackage1Option {
    local @ARGV = @ARGV;
    getopt('b');
    our ($opt_b);    
    my $argb = $opt_b || '';    
    return $argb;
}        # end of scope, original @ARGV restored

虽然像Sinan和simbabque说的那样,这是一个非正统的设计,你应该重新考虑。

答案 1 :(得分:1)

解决难题的最简单方法是在程序的入口点进行命令行参数解析,其中参数的值可以保存在散列中,您可以在散列中为未指定的值提供默认值。然后,您可以决定如何传达每个模块感兴趣的值(例如包变量或构造函数参数)。

我强烈建议远距离采取这种行动,但是这里可能会如何自动设置不同模块中包变量的值以响应命令行中给出的值。每个包都负责声明它感兴趣的命令行开关。

#!/usr/bin/env perl

use strict;
use warnings;

package X;

our @PACKAGE_OPTS = qw( v x: );

our ($OPT_V, $OPT_X);

sub func {
    print "$OPT_V\t$OPT_X\n";
}

package Y;

our @PACKAGE_OPTS = qw( t y: z);

our ($OPT_T, $OPT_Y, $OPT_Z);

sub func {
    print join("\t", $OPT_T, $OPT_Y, $OPT_Z), "\n";
}

package main;

use Getopt::Std;

main();

sub main {
    init_opts(qw( X Y ));
    X::func();
    Y::func();
}

sub init_opts {
    my %opts;
    my $opt_string;
    my %opt_to_package;

    for my $pkg ( @_ ) {
        my @opts = eval "\@${pkg}::PACKAGE_OPTS";
        $opt_string .= join '', @opts;

        for my $opt ( @opts ) {
            (my $var = $opt) =~ s/[^A-Za-z]+//g;
            $opts{$var} = '-not provided-';
            $opt_to_package{$var} = $pkg;
        }
    }

    getopts($opt_string, \%opts);

    for my $opt (keys %opts) {
        my $pkg = $opt_to_package{$opt};
        my $var = 'OPT_' . uc $opt;
        eval "\$${pkg}::${var} = \$opts{\$opt}"
    }

    return;
}

输出:

C:\...\Temp> perl tt.pl -zvx a -y b
1       a
-not provided-  b       1
相关问题