develooper Front page | perl.perl5.porters | Postings from January 2005

RE: [perl #33940] Interrelations of DESTROY and eval are not welldocumented

From:
DeRykus, Charles E
Date:
January 26, 2005 15:54
Subject:
RE: [perl #33940] Interrelations of DESTROY and eval are not welldocumented
Message ID:
5DF8FDE8DFE8744388602480FDCC0E3106CF1097@xch-nw-23.nw.nos.boeing.com


>The questions answer to which seems missing in Perl docs is:
>
>Consider code:
> 
eval {
>    my $obj1 = Class1->new;
>    {
>      my $obj2 = Class2->new;
>      # Suppose Class2->DESTROY calls 'die "2"'
>    }
>    # Suppose Class1->DESTROY also 'die "1"'
>  }
>  

>>There are TONS of edge cases (and not so edge cases) around eval/die semantics. They'll >>all confuse you at first. The one that bit me hardest was actually fairly simple:

>>        $start = time();
>>        @lines = eval {
>>           $SIG{ALRM} = sub {die "timeout"};
>>            alarm(2);
>>            my $cmd = IO::File->new("sleep 5|");
>>            $cmd->getlines();
>>        };
>>        die $@ if $@ && ($@ !~ /timeout/);
>>        $end = time();
>>        $delta = $end-$start;
>>        print "Got ",scalar(@lines)," answers in $delta seconds.\n";

>>Of course, this fails (exits in the full 5 seconds) unless you move the declaration of 
>>$cmd outside of the eval so that destruction doesn't attempt to wait(2) on the child, but >>that's very non-obvious to someone who is thinking in terms of "my signal handler said 
>>die, so we jump outside of the eval."

If the child wait is the culprit, I'm confused why this behaves differently:

    # my $cmd = IO::File->new("sleep 5|");
    my $cmd = IO::File->new("cat /dev/zero|");


The 2 second timeout works as expected now; whereas, the potentially dueling duo
(alarm/sleep) in your example seem risky...

--
Charles DeRykus



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About