Получите поведение переключателя / случая в Perl 5 - PullRequest
27 голосов
/ 10 мая 2009

Есть ли в Perl 5 аккуратный способ создания регистра или оператора switch? Мне кажется, они должны включить переключатель на версии 6 ..

Мне нужна эта структура управления в скрипте, и я слышал, что вы можете импортировать "модуль переключения". Но как я могу достичь этого без импорта, чтобы минимизировать зависимости и приобрести мобильность?

Ответы [ 5 ]

57 голосов
/ 10 мая 2009

Если вы используете Perl 5.10, у вас есть given / when, который является оператором переключения (обратите внимание, он может сделать больше, чем сравнение с регулярными выражениями, прочитайте связанные документы, чтобы увидеть его полный потенциал ):

#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 ), который выдает вам ложные инструкции switch с помощью исходных фильтров , но, насколько я понимаю, он хрупкий :

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; }
}
17 голосов
/ 10 мая 2009

Предложение в программировании на Perl:


for ($string) {
    /abc/ and do {$abc    = 1; last;};
    /def/ and do {$def    = 1; last;};
    /xyz/ and do {$xyz    = 1; last;};
    $nothing = 1;
}
9 голосов
/ 12 мая 2009

Просто краткий комментарий о модуле ядра Switch , о котором пару раз упоминалось в ответах. Данный модуль опирается на исходные фильтры. Среди прочего, это может привести к неправильным строкам, сообщаемым об ошибках. Это так плохо, что никто из разработчиков ядра не помнит и не заботится о том, чтобы вспомнить, почему он был принят в ядро ​​perl.

Кроме того, Switch.pm будет первым модулем Perl, когда-либо удаленным из ядра perl. В следующем основном выпуске Perl, 5.12.0, он все еще будет, хотя и с предупреждением об устаревании. Это предупреждение об устаревании исчезнет, ​​если вы явно установите Switch.pm из CPAN. (Вы получаете то, что просите.) В следующем выпуске, 5.14, Switch.pm будет полностью удален из ядра.

8 голосов
/ 11 мая 2009

Эквивалентное решение, которое мне нравится, это таблица отправки .

my $switch = {
  'case1' => sub { print "case1"; },
  'case2' => sub { print "case2"; },
  'default' => sub { print "unrecognized"; }
};
$switch->{$case} ? $switch->{$case}->() : $switch->{'default'}->();
0 голосов
/ 08 августа 2013
print("OK : 1 - CANCEL : 2\n");
my $value = <STDIN>;
SWITCH: {
    ($value == 1) && last(SWITCH);
    ($value == 2) && do {print("Cancelled\n"); exit()};
    print("??\n");
}
...