package Foo;
use strict;
use Carp qw( croak );
sub do_foo {
croak "Please don't give arguments to do_foo(), got '@_'"
unless 0 == @_;
};
package Baz;
use strict;
sub do_baz {
Foo::do_foo( @_ );
};
package Bar;
use strict;
use vars qw(@CARP_NOT);
@CARP_NOT=('Foo'); # we are invisible to Foo
sub do_bar {
my( $first,@rest )= @_;
print "Got '$first', Preparing for foo(@rest)\n";
Foo::do_foo(@rest);
};
package main;
print "Bar\n";
Bar::do_bar('one'); # does not croak
print "do_foo\n";
eval { Foo::do_foo('one','two'); }; print $@;
# Please don't give arguments to do_foo(), got 'one two' at tmp.pl lin
+e 34.
print "do_bar\n";
eval { Bar::do_bar('one','two'); }; print $@;
# Please don't give arguments to do_foo(), got 'two' at tmp.pl line 37
+.
print "do_baz\n";
eval { Baz::do_baz('one','two'); }; print $@;
# Please don't give arguments to do_foo() at tmp.pl line 14.
Here, the package Bar does not show up as an error location, because it sets itself up to be invisible for all errors raised by Foo. Baz does get raised as the error location in the last call, which may or may not be helpful to the user using Baz.
For a more elaborate example of this, MozRepl::RemoteObject::Instance has some helper classes for tie-ing scalars, arrays and hashes. But all errors due to operations on these should be transparent to the user and show up in the user code, which is achieved by setting up @CARP_NOT in each of the tied classes so that errors raised in MozRepl::RemoteObject::Instance never show up as originating in the helper class. |