summaryrefslogtreecommitdiff
path: root/pod/perlcall.pod
diff options
context:
space:
mode:
Diffstat (limited to 'pod/perlcall.pod')
-rw-r--r--pod/perlcall.pod86
1 files changed, 76 insertions, 10 deletions
diff --git a/pod/perlcall.pod b/pod/perlcall.pod
index 50600f5d1c..996c9145d0 100644
--- a/pod/perlcall.pod
+++ b/pod/perlcall.pod
@@ -295,6 +295,37 @@ from the stack.
See I<Using G_EVAL> for details of using G_EVAL.
+=head2 G_KEEPERR
+
+You may have noticed that using the G_EVAL flag described above will
+B<always> 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<eval {}> 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<eval {}>, 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<tie> 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<perl_call_*> 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<Using G_KEEPERR> 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<Subtract>.
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<errgv> is a perl global of type C<GV *> that points to the
+symbol table entry containing the error. C<GvSV(errgv)> therefore
+refers to the C equivalent of C<$@>.
+
=item 3.
Note that the stack is popped using C<POPs> in the block where
-C<SvTRUE(sv)> is true. This is necessary because whenever a
+C<SvTRUE(GvSV(errgv))> is true. This is necessary because whenever a
I<perl_call_*> function invoked with G_EVAL|G_SCALAR returns an error,
the top of the stack holds the value I<undef>. 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<undef>.
=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<eval {}>. 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<perl_call_pv> 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<perl_call_pv> 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 <pmarquess@bfsec.bt.co.uk>
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