web-dev-qa-db-ja.com

Perl 5でスイッチ/ケースの動作を取得する

Perl 5でcaseまたはswitchステートメントを作成するためのきちんとした方法はありますか?彼らにはバージョン6のスイッチが含まれているようです。

この制御構造がスクリプトに必要です。「スイッチモジュール」をインポートできると聞きました。しかし、依存関係を最小限に抑えて移植性を獲得するために、インポートなしでそれをどのように実現できますか?

27
lurks

Perl 5.10を使用している場合、 given/when はswitchステートメントです(注、正規表現と比較する以上のことができます。リンクされたドキュメントを参照してください)その完全な可能性を見てください):

#or any of the dozen other ways to tell 5.10 to use its new features
use feature qw/switch/; 

given($string) {
    when (/^abc/) { $abc     = 1; }
    when (/^def/) { $def     = 1; }
    when (/^xyz/) { $xyz     = 1; }
    default       { $nothing = 1; }
}

Perl 5.8以前を使用している場合は、if/elsif/elseステートメントを実行する必要があります。

if    ($string =~ /^abc/) { $abc     = 1; }
elsif ($string =~ /^def/) { $def     = 1; }
elsif ($string =~ /^zyz/) { $xyz     = 1; }
else                      { $nothing = 1; }

またはネストされた 条件演算子(?:

$string =~ /^abc/ ? $abc     = 1  :
$string =~ /^def/ ? $def     = 1  :
$string =~ /^xyz/ ? $xyz     = 1  :
                    $nothing = 1;

Core Perl( Switch )にモジュールがあります source filters を介して偽のswitchステートメントを提供しますが、それは fragile であることが私の理解です:

use Switch;

switch ($string) {
    case /^abc/ {
    case /^abc/ { $abc     = 1 }
    case /^def/ { $def     = 1 }
    case /^xyz/ { $xyz     = 1 } 
    else        { $nothing = 1 }
}

または代替構文

use Switch 'Perl6';

given ($string) {  
    when /^abc/ { $abc     = 1; }
    when /^def/ { $def     = 1; }
    when /^xyz/ { $xyz     = 1; }
    default     { $nothing = 1; }
}
57
Chas. Owens

プログラミングPerlでの提案は次のとおりです。


for ($string) {
    /abc/ and do {$abc    = 1; last;};
    /def/ and do {$def    = 1; last;};
    /xyz/ and do {$xyz    = 1; last;};
    $nothing = 1;
}
17
Nathan Fellman

回答で何度か言及されているコア Switch モジュールに関する短いコメント。問題のモジュールはソースフィルターに依存しています。とりわけ、それはエラーに対して誤った行が報告される可能性があります。そもそもコア開発者の誰もが、そもそもなぜそれがPerlコアに受け入れられたのかを本当に覚えていたり、気にしたりしていないほど悪い。

さらに、Switch.pmは、Perlコアから削除される最初のPerlモジュールになります。 Perlの次のメジャーリリースである5.12.0には、非推奨の警告が表示されますが、引き続きリリースされます。 CPANからSwitch.pmを明示的にインストールすると、この非推奨の警告は消えます。 (あなたが求めるものを手に入れます。)次のリリース5.14では、Switch.pmは完全にコアから削除されます。

9
tsee

私が気に入っている同等のソリューションは、 ディスパッチテーブル です。

my $switch = {
  'case1' => sub { print "case1"; },
  'case2' => sub { print "case2"; },
  'default' => sub { print "unrecognized"; }
};
$switch->{$case} ? $switch->{$case}->() : $switch->{'default'}->();
8
jiggy
print("OK : 1 - CANCEL : 2\n");
my $value = <STDIN>;
SWITCH: {
    ($value == 1) && last(SWITCH);
    ($value == 2) && do {print("Cancelled\n"); exit()};
    print("??\n");
}
0
Weeble