Как переписать этот блок eval - PullRequest
2 голосов
/ 18 июня 2010

Этот код пахнет ... как мне лучше переписать его?

my $record;

eval {
    while (
        # undef $record here, so if getRecord() failed, nothing will be written
        # in the reject file
        do { undef $record; defined( $record = $dataFile->getRecord ) }
    ) {
        $LT_DataFile->encode($record);
    } 
    1;
};

if ( my $error = $@ ) {
    $rejectFile->writeRecord( $error, $record );
}

Спасибо.

Ответы [ 3 ]

8 голосов
/ 18 июня 2010

Вам не нужна переменная в части catch, потому что при выполнении там ее содержимое всегда будет undef.Замена этого литеральным значением позволяет ограничить $record меньшей областью действия.

use Try::Tiny;
try {
    while (defined(my $record = $dataFile->getRecord)) {
        $LT_DataFile->encode($record);
    }
} catch {
    $rejectFile->writeRecord($_, undef);    # T::T puts error in $_
}
2 голосов
/ 18 июня 2010

Я бы реорганизовал цикл while в

while (defined( $record = $dataFile->getRecord )) {
    $LT_DataFile->encode($record);
} continue {
    undef $record;
}

. Блок continue выполняется после каждой итерации перед проверкой условного выражения.Он будет по-прежнему вызываться, если ваш код использует next для начала следующей итерации раньше.Если вы вряд ли позвоните next, то упрощение кода до

while (defined( $record = $dataFile->getRecord )) {
    $LT_DataFile->encode($record);
    undef $record;
}

также будет работать.

2 голосов
/ 18 июня 2010

Хорошо, переработал мой ответ.

Я думаю, что проблема REAL в том, как вы обрабатываете ошибки.На первый взгляд сбивает с толку возможность увидеть один обработчик ошибок, когда у вас есть несколько мест, где что-то может пойти не так.Я вижу две альтернативы.

Во-первых, оставьте это в основном таким же, как сейчас, но определенно проверьте для каждого типа ошибки:

my $record;
eval {
    while (defined( $record = $dataFile->getRecord )) {
        $LT_DataFile->encode($record);
    } 
};
if (my $error = $@) {
    given ($error) {
        when (/get record error/) {  $rejectFile->writeRecord($_, undef);   }
        when (/encode error/)     {  $rejectFile->writeRecord($_, $record); }
    }
}

Таким образом, вы явно указалиВы обрабатываете свои ошибки.Конечно, с Try :: Tiny это упрощается до следующего

my $record;
try {
    while (defined( $record = $dataFile->getRecord )) {
        $LT_DataFile->encode($record);
    } 
} catch {
    when (/get record error/) {  $rejectFile->writeRecord($_, undef);   }
    when (/encode error/)     {  $rejectFile->writeRecord($_, $record); }
}

В качестве альтернативы, вы можете добавить лексическую запись в ответ Daxim .Это требует второго eval или try, ближе к проблеме и добавления вызова last:

eval {
    while (defined( my $record = $dataFile->getRecord )) {
        eval { $LT_DataFile->encode($record) };
        if (my $error = $@) { $rejectFile->writeRecord($error, $record); last }
    } 
};
if (my $error = $@) {
    $rejectFile->writeRecord($error, undef);
}

К сожалению, этот метод не будет работать с Try :: Tiny, потому что блоки, переданные для попытки, на самом делеsubrefs.

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