2017-06-08 6 views
0

[perlのスクリプト] perl_script.pl -b "HELLO" 私はPerlのGetopt :: Stdを2つのパッケージで使用できますか?

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; 
} 

-v 2つの別々のパッケージから2つの関数を呼び出し、各関数は異なるオプションを使用します。

私はこれを試しましたが、私は-bのオプションしか得ていません。 -vオプションは、-bを使用する関数を削除すると機能します。

ご迷惑をおかけしますが、これは私のオリジナルコードの要約です。

私の質問が混乱している場合は教えてください。ありがとう:)

+5

は概念的には、あなたのコードではありません基礎と脆弱な混乱です:*あなたのプログラムに渡されたコマンドライン引数の単一のセットがあります。 @ ARGVを何度も何度も何度も処理し続けるのは意味がありません。あなたのモジュールは '@ ARGV'処理をしてはいけません。つまり、あなたは '@ ARGV'のコピーを作ることができました...しかし、私はあなたの代わりにあなたのデザインを修正することをお勧めします。 –

+5

私はSinanに同意します。コマンドライン引数の処理をプログラムに入れ、各モジュールが望むものを得るために引数をマップする必要があります。あるいは、各モジュールにコマンドラインのインタフェースを定義できる機能を与えることができます。次に、プログラムがそれを使って引数の完全なリストをコンパイルし、解析することができます。 – simbabque

答えて

2

Getopt::Stdは、グローバル@ARGVアレイで動作し「消費」します。 getoptまたはgetoptsを複数回実行するには、localを使用して@ARGVの一時コピーを作成します。

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

シナンとsimbabqueのようなものの、これはおそらく再考すべき異例のデザインである、と言います。

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 
関連する問題