Open p5pRT opened 19 years ago
This is a bug report for perl from porton@ex-code.com\, generated with the help of perlbug 1.35 running under perl v5.8.4.
----------------------------------------------------------------- I reasonably detailed scanned perlobj\, perltoot\, perlbot manpages\, read "die" and "eval" entries in perlfunc and found no answer.
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"' }
What is now $@?
I'd like if ($@ eq "1") after this eval block (outer object to allow to override inner exception)\, but I found no warranty for ($@ eq "1") in Perl docs.
In article \rt\-3\.0\.11\-33940\-106489\.16\.0611746958661@​perl\.org\, "Victor Porton\,\,\," (via RT) \perlbug\-followup@​perl\.org writes:
I reasonably detailed scanned perlobj\, perltoot\, perlbot manpages\, read "die" and "eval" entries in perlfunc and found no answer.
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"' }
What is now $@?
I'd like if ($@ eq "1") after this eval block (outer object to allow to override inner exception)\, but I found no warranty for ($@ eq "1") in Perl docs.
Sorry\, it won't do what you want exactly.
dies in DESTROY append "\t(in cleanup)error message" to the existing $@. It's documented in a rather obscure place\, in perlcall under G_KEEPERR\, and rather sideways even there. (you need to read rather carefully to infer it will happen for die in DESTROY) And it has some weird\, undocumented and broken trickery to try to avoid duplicate messages too.
I agree with you that it deserves a more highlevel explanation in a more visible place.
The RT System itself - Status changed from 'new' to 'open'
On Wed\, 2005-01-26 at 15:24\, Ton Hospel wrote:
In article \rt\-3\.0\.11\-33940\-106489\.16\.0611746958661@​perl\.org\, "Victor Porton\,\,\," (via RT) \perlbug\-followup@​perl\.org writes:
I reasonably detailed scanned perlobj\, perltoot\, perlbot manpages\, read "die" and "eval" entries in perlfunc and found no answer.
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."
I really wish at times that Perl had a safe eval that you could absolutely exit from.
-- ☎ 781-324-3772 ✉ ajs@ajs.com ☷ http://www.ajs.com/~ajs
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
This is now documented in perl5140delta\, but it still needs to be documented clearly elsewhere.
On Sat Apr 30 22:49:35 2011\, sprout wrote:
This is now documented in perl5140delta\, but it still needs to be documented clearly elsewhere.
Is this the section of perl5140delta you were referring to?
########## Stack unwinding
The protocol for unwinding the C stack at the last stage of a die has changed how it identifies the target stack frame. This now uses a separate variable PL_restartjmpenv \, where previously it relied on the blk_eval.cur_top_env pointer in the eval context frame that has nominally just been discarded. This change means that code running during various stages of Perl-level unwinding no longer needs to take care to avoid destroying the ghost frame. ##########
(I ask because this RT number is not explicitly referenced in that document.)
Where else should this documentation go (so that we can close the ticket)?
Thank you very much. Jim Keenan
James E Keenan via RT wrote:
Where else should this documentation go (so that we can close the ticket)?
It should be described in perlguts.
-zefram
Migrated from rt.perl.org#33940 (status was 'open')
Searchable as RT33940$