5

Why doesn't the subroutine with try/catch give me the same results as the eval-version does?

#!/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"
brian d foy
  • 129,424
  • 31
  • 207
  • 592
sid_com
  • 24,137
  • 26
  • 96
  • 187

1 Answers1

12

You are missing the final semicolon on the try/catch blocks.

You have:

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

So, you have code that is equivalent to: try( CODEREF, catch( CODEREF, return ) );

Update:

I forgot to mention, to fix your code simply change 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;
}
daotoad
  • 26,689
  • 7
  • 59
  • 100