X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlcall.pod;h=996c9145d088096d9bd1eb3187a32a009fb36a38;hb=4d9142afa100a96f07b67cd4b087273df8c60543;hp=50600f5d1ceb120cdff1d0d245a46062afe42dff;hpb=8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlcall.pod b/pod/perlcall.pod index 50600f5..996c914 100644 --- a/pod/perlcall.pod +++ b/pod/perlcall.pod @@ -295,6 +295,37 @@ from the stack. See I for details of using G_EVAL. +=head2 G_KEEPERR + +You may have noticed that using the G_EVAL flag described above will +B clear the C<$@> variable and set it to a string describing +the error iff there was an error in the called code. This unqualified +resetting of C<$@> can be problematic in the reliable identification of +errors using the C mechanism, because the possibility exists +that perl will call other code (end of block processing code, for +example) between the time the error causes C<$@> to be set within +C, and the subsequent statement which checks for the value of +C<$@> gets executed in the user's script. + +This scenario will mostly be applicable to code that is meant to be +called from within destructors, asynchronous callbacks, signal +handlers, C<__DIE__> or C<__WARN__> hooks, and C functions. In +such situations, you will not want to clear C<$@> at all, but simply to +append any new errors to any existing value of C<$@>. + +The G_KEEPERR flag is meant to be used in conjunction with G_EVAL in +I functions that are used to implement such code. This flag +has no effect when G_EVAL is not used. + +When G_KEEPERR is used, any errors in the called code will be prefixed +with the string "\t(in cleanup)", and appended to the current value +of C<$@>. + +The G_KEEPERR flag was introduced in Perl version 5.002. + +See I for an example of a situation that warrants the +use of this flag. + =head2 Determining the Context As mentioned above, you can determine the context of the currently @@ -892,7 +923,6 @@ and some C to call it { dSP ; int count ; - SV * sv ; ENTER ; SAVETMPS; @@ -907,10 +937,9 @@ and some C to call it SPAGAIN ; /* Check the eval first */ - sv = GvSV(gv_fetchpv("@", TRUE, SVt_PV)); - if (SvTRUE(sv)) + if (SvTRUE(GvSV(errgv))) { - printf ("Uh oh - %s\n", SvPV(sv, na)) ; + printf ("Uh oh - %s\n", SvPV(GvSV(errgv), na)) ; POPs ; } else @@ -950,10 +979,9 @@ I. The code - sv = GvSV(gv_fetchpv("@", TRUE, SVt_PV)); - if (SvTRUE(sv)) + if (SvTRUE(GvSV(errgv))) { - printf ("Uh oh - %s\n", SvPVx(sv, na)) ; + printf ("Uh oh - %s\n", SvPV(GvSV(errgv), na)) ; POPs ; } @@ -961,10 +989,14 @@ is the direct equivalent of this bit of Perl print "Uh oh - $@\n" if $@ ; +C is a perl global of type C that points to the +symbol table entry containing the error. C therefore +refers to the C equivalent of C<$@>. + =item 3. Note that the stack is popped using C in the block where -C is true. This is necessary because whenever a +C is true. This is necessary because whenever a I function invoked with G_EVAL|G_SCALAR returns an error, the top of the stack holds the value I. Since we want the program to continue after detecting this error, it is essential that @@ -973,6 +1005,39 @@ the stack is tidied up by removing the I. =back +=head2 Using G_KEEPERR + +Consider this rather facetious example, where we have used an XS +version of the call_Subtract example above inside a destructor: + + package Foo; + sub new { bless {}, $_[0] } + sub Subtract { + my($a,$b) = @_; + die "death can be fatal" if $a < $b ; + $a - $b; + } + sub DESTROY { call_Subtract(5, 4); } + sub foo { die "foo dies"; } + + package main; + eval { Foo->new->foo }; + print "Saw: $@" if $@; # should be, but isn't + +This example will fail to recognize that an error occurred inside the +C. Here's why: the call_Subtract code got executed while perl +was cleaning up temporaries when exiting the eval block, and since +call_Subtract is implemented with I using the G_EVAL +flag, it promptly reset C<$@>. This results in the failure of the +outermost test for C<$@>, and thereby the failure of the error trap. + +Appending the G_KEEPERR flag, so that the I call in +call_Subtract reads: + + count = perl_call_pv("Subtract", G_EVAL|G_SCALAR|G_KEEPERR); + +will preserve the error and restore reliable error handling. + =head2 Using perl_call_sv In all the previous examples I have 'hard-wired' the name of the Perl @@ -1829,8 +1894,9 @@ Paul Marquess Special thanks to the following people who assisted in the creation of the document. -Jeff Okamoto, Tim Bunce, Nick Gianniotis, Steve Kelem and Larry Wall. +Jeff Okamoto, Tim Bunce, Nick Gianniotis, Steve Kelem, Gurusamy Sarathy +and Larry Wall. =head1 DATE -Version 1.1, 17th May 1995 +Version 1.2, 16th Jan 1996