Perl eval block (вложенный eval?) - PullRequest
       0

Perl eval block (вложенный eval?)

0 голосов
/ 08 октября 2018

Я выполняю некоторую команду в случае, если elsif else основан на каком-то условии, и сохраняю код возврата как $ status.

eval {
    if ($condition1)
    {
      $status = system ...
    }
    elsif ($condition2)
    {
      foreach my $scenario (@setting) {
         next unless $scenario;
         $status = system <somecommand> 
         }
    }
    elsif ($condition3)
    {
      $status = system ...
    }
    else
    {
      $status = system ...
    }
};
die $@ if $@;
return ($status !=0);

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

elsif ($condition2)
{
  foreach my $scenario (@setting) {
     next unless $scenario;
     $status = system <somecommand> 
     }
}

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Форма BLOCK eval - это встроенный механизм для обработки «исключений» в Perl, то есть die .

. Таким образом, это естественно для«вкладывать» его, в том смысле, что каждый уровень имеет свой собственный

eval { func(...) }; if ($@) { ... }

sub func {
    ...
    eval { func_lower(...) };
    if ($@) {
        # handle it: recover or re-throw for the higher-level handlers
    }
    ...
}

sub func_lower {
    ...
    eval { func_lower_yet(...) };
    if ($@) {
        # handle it: recover or re-throw for the higher-level handlers
    }
    ...
}

. Таким образом, на каждом уровне можно решить, можно ли разрешить исключительное поведение, а если нет, то перебросить (выпустить die снова), поскольку более высокий уровень может быть лучше информирован, чтобы иметь дело с ним.

Исключения в Perl также "всплывают", поэтому, если исключение не обработано на одном уровне, оно распространяется вверх по стеку вызовов, и следующий уровень вверх все еще может с ним работать (программа не завершается доосновной сбит с исключением, которое он не обрабатывает).

Такая типичная структура вложенных вызовов немного забита в вашей последовательности if-elsif, но она все еще соответствует

eval {
    if    ($condition1) { ... }
    elsif ($condition2) { 
        eval {
            ...
        };
        if ($@) {
            # issue a warning, perhaps set some flag, and continue 
            # or throw a die for the higher-level eval 
        }
    }
    elsif ...
};
if ($@) {
    # interrogate details
}

Теперь вы можете изолировать ошибки от $condition2, чтобы им не приходилось вызывать внешние eval.

Обратите внимание, что вы можете "бросать" объекты в die, например, простого классавы пишете, чтобы собрать воедино ваши потребности, что обеспечивает гораздо большую гибкость для обработчиков.Также обратите внимание, что для этого есть модули CPAN.

0 голосов
/ 08 октября 2018
die $@ if $@;

говорит вашей программе прервать работу, если что-то пошло не так в блоке eval.если вы удалите эту строку, все будет в порядке.

после удаления вы можете заменить свою последнюю строку на что-то вроде:

return $@ ? 'something went wrong' : $status;

, если вы все еще хотите обнаружить, что что-то пошло не так безостанавливать все, но это не обязательно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...