Skip Menu |

This queue is for tickets about the Syntax-Keyword-Try CPAN distribution.

Report information
The Basics
Id: 118415
Status: resolved
Priority: 0/
Queue: Syntax-Keyword-Try

People
Owner: Nobody in particular
Requestors: leonerd-cpan [...] leonerd.org.uk
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 0.04



Subject: localise $@
Otherwise nested try-in-catch behaves incorrectly: try { die "failure\n"; } catch { print STDERR "Before: dollarat is $@\n"; try { 1 } catch {} print STDERR "After dollarat is now $@\n"; } Currently outputs: Before: dollarat is failure After dollarat is now -- Paul Evans
Patch attached. -- Paul Evans
Subject: rt118415.patch
=== modified file 'lib/Syntax/Keyword/Try.xs' --- lib/Syntax/Keyword/Try.xs 2016-11-25 00:10:28 +0000 +++ lib/Syntax/Keyword/Try.xs 2016-11-25 15:05:12 +0000 @@ -77,6 +77,14 @@ return op; } +#define newLOCALISEOP(gv) MY_newLOCALISEOP(aTHX_ gv) +static OP *MY_newLOCALISEOP(pTHX_ GV *gv) +{ + OP *op = newGVOP(OP_GVSV, 0, gv); + op->op_private |= OPpLVAL_INTRO; + return op; +} + #define lex_consume(s) MY_lex_consume(aTHX_ s) static int MY_lex_consume(pTHX_ char *s) { @@ -270,19 +278,24 @@ ), newLISTOP(OP_SCOPE, 0, catch, NULL) ); + + /* localise $@ beforehand */ + ret = op_prepend_elem(OP_LINESEQ, newLOCALISEOP(PL_errgv), ret); } /* If there's a finally, make - * $RET = { OP_PUSHFINALLY($FINALLY); $RET } + * $RET = OP_PUSHFINALLY($FINALLY); $RET */ if(finally) { + ret = op_prepend_elem(OP_LINESEQ, newPUSHFINALLYOP(finally), ret); + } + + /* If there's either catch or finally, block-wrap the result + */ + if(catch || finally) { ret = newLISTOP(OP_LEAVE, 0, - op_prepend_elem(OP_LINESEQ, newOP(OP_ENTER, 0), - op_prepend_elem(OP_LINESEQ, newPUSHFINALLYOP(finally), - ret - ) - ), NULL - ); + op_prepend_elem(OP_LINESEQ, newOP(OP_ENTER, 0), ret), + NULL); } *op = ret; === added file 't/14try-localises.t' --- t/14try-localises.t 1970-01-01 00:00:00 +0000 +++ t/14try-localises.t 2016-11-25 15:05:12 +0000 @@ -0,0 +1,20 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More; + +use Syntax::Keyword::Try; + +# try/catch localises $@ (RT118415) +{ + eval { die "oopsie" }; + like( $@, qr/^oopsie at /, '$@ before try/catch' ); + + try { die "another failure" } catch {} + + like( $@, qr/^oopsie at /, '$@ after try/catch' ); +} + +done_testing;
Was released in 0.04 -- Paul Evans