Почему Perl's Try :: Tiny's try / catch не дает мне такие же результаты, как eval? - PullRequest
5 голосов
/ 20 мая 2010

Почему подпрограмма с try / catch не дает мне таких же результатов, как eval-версия?

#!/usr/bin/env perl
use warnings; use strict;
use 5.012;
use Try::Tiny;

sub shell_command_1 {
    my $command = shift;
    my $timeout_alarm = shift;
    my @array;
    eval {
        local $SIG{ALRM} = sub { die "timeout '$command'\n" };
        alarm $timeout_alarm;
        @array = qx( $command );
        alarm 0;
    };
    die $@ if $@ && $@ ne "timeout '$command'\n";
    warn $@ if $@ && $@ eq "timeout '$command'\n";
    return @array;
}
shell_command_1( 'sleep 4', 3 );
say "Test_1";

sub shell_command_2 {
    my $command = shift;
    my $timeout_alarm = shift;
    my @array;
    try {
        local $SIG{ALRM} = sub { die "timeout '$command'\n" };
        alarm $timeout_alarm;
        @array = qx( $command );
        alarm 0;
    }
    catch {
    die $_ if $_ ne "timeout '$command'\n";
    warn $_ if $_ eq "timeout '$command'\n";
    }
    return @array;
}
shell_command_2( 'sleep 4', 3 );
say "Test_2"

1 Ответ

12 голосов
/ 20 мая 2010

Вам не хватает последней точки с запятой в блоках try / catch.

У вас есть:

try  {
    ...
}
catch {
    ...
}
return;

Итак, у вас есть код, который эквивалентен: try( CODEREF, catch( CODEREF, return ) );

Обновление:

Я забыл упомянуть, чтобы исправить ваш код, просто измените shell_command_2:

sub shell_command_2 {
    my $command = shift;
    my $timeout_alarm = shift;
    my @array;
    try {
        local $SIG{ALRM} = sub { die "timeout '$command'\n" };
        alarm $timeout_alarm;
        @array = qx( $command );
        alarm 0;
    }
    catch {
        die $_ if $_ ne "timeout '$command'\n";
        warn $_ if $_ eq "timeout '$command'\n";
    };           # <----- Added ; here <======= <======= <======= <=======
    return @array;
}
...