-1

switch ステートメントを使用して、端末で提供される引数を確認しています。エンドユーザーが提供する場合、提供されたスクリプトは正常に機能しています

      $perl test.pl -help 

ただし、ユーザーが以下のオプションを指定している場合、サブルーチンは再帰的に呼び出されません。

      $perl test.pl -link abc -web test.com

提案してください!

      use Switch;
      #perl test.pl -help
      #perl test.pl -link abc -web test.com

      sub CheckArgument {

       my ($argv)   = shift @_;
       local $\     = "\n";
       print "\$argv : $argv\n";

       switch($argv) {
                  case /-help/ {
                             print "Usage : $0 -link <link name> -web <website name>";
                             print "Usage : $0 -list_web_name";
                             exit;
                  }
                  case /-list_web_name/ {
                             print "Currently Support following site";
                             foreach (qw/abc/) {
                                        print "$_";
                              }
                             exit;
                   }
                  case /-link/ {
                             CheckArgument($ARGV[3]);
                  }
                  case /-web/ {
                             print "argument provided : @ARGV\n";       
                  }
                  default {
                             CheckArgument("-help");
                  }
        }
       }
4

2 に答える 2

2

まず、Switchソース フィルターは非推奨です。使用しないでください。

以下は、理解しやすいかもしれない再帰なしでコードを書き直したものです。

use 5.010;
sub CheckArgument {
  my $_ = shift;

  ARG: {
    if (/-help/) {
      say "Usage: $0 -link <link-name> -web <website-name>";
      say "Usage: $0 -list_web_name";
    } elsif (/-list_web_name/) {
      say "Currently supporting following sites:";
      say for qw/a b c/;
    } elsif (/-link/) {
      $_ = $ARGV[3];
      redo ARG;
    } elsif (/-web/) {
      say "arguments provided : @ARGV\n";       
    } else {
      $_ = "-help";
      redo ARG;
    }
  }
  exit;
}

に設定@ARGVqw/ -link x y -web/、引数としてそのサブルーチンを呼び出すと、@ARGV次の出力が得られます。

arguments provided : -link x y -web

まず、 を見てみましょう-link。これにより、@ARGV見ている変数に 4 番目の要素を入れます。-webこれは次の繰り返しでも保持され、すべてのコマンド ライン引数が出力されます。この解析戦略は決して堅牢ではありません。

再帰よりも、未処理の引数がある間にループすることをお勧めします。スイッチを認識する場合は、そのスイッチとその値を arglist から削除します。引数が理解できない場合は、使用法を出力してください:

use 5.010;
# I use 5.010 for the C<say> function, but if we're already using it,
# we could just as well use given/when. Wouldn't make it much prettier.
sub ProcessArguments {
  ARG: while (@_) {
    my $_ = shift;
    if (/\A-?-list_web_name\z/) {
      say "Currently supporting following sites:";
      say for qw/a b c/;
    } elsif (/\A-?-link\z/) {
      my $link_name = shift;
      shift() =~ /\A-?-web\z/ or do { Usage(); exit };
      my $website_name = shift;
      do_something_with($link_name, $website_name);
    } elsif (/\A-?-web\z/) {
      my $website_name = shift;
      shift() =~ /\A-?-link\z/ or do {Usage(); exit };
      my $link_name = shift;
      do_something_with($link_name, $website_name);
    } else {
      Usage();
      exit;
    }
  }
}
sub Usage {
  say "Usage: $0 -link <link-name> -web <website-name>";
  say "Usage: $0 -list_web_name";
}

ああ、このひどいボイラープレート、終わりのない繰り返し。誰かがすでに私たちにオプションを提供するものを書いていたら、それは素晴らしいことではないでしょうか? CPANモジュールのような?

use Getopt::Long;
use 5.010;
sub ProcessArguments {
  my $list_web_name;
  my $help;
  my ($link_name, $website_name);
  GetOptions
    'list-web-name' => \$list_web_name,
    'help'          => \$help,
    'link=s'        => \$link_name,
    'web=s'         => \$website_name;
  if ($help) {
      Usage();
  } elsif ($list_web_name) {
      say "Currently supporting following sites:";
      say for qw/a b c/;
  } elsif (defined $link_name and defined $website_name) {
      do_something_with($link_name, $website_name);
  } else {
      Usage();
  }
}

そして、それはその方法です。

于 2013-04-24T22:06:00.403 に答える