summaryrefslogtreecommitdiff
path: root/lib/Fatal.pm
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>2000-03-07 20:18:54 +0000
committerGurusamy Sarathy <gsar@cpan.org>2000-03-07 20:18:54 +0000
commit91c7a8804c6d3adc7e73ca2956160b00f07dd6a2 (patch)
tree5fe42983ae39ddd2ff206718725fbc245fce51f8 /lib/Fatal.pm
parent60a48b2d850245d0a8759f6873cb9e007b6da62b (diff)
downloadperl-91c7a8804c6d3adc7e73ca2956160b00f07dd6a2.tar.gz
support :void to enable croaking only in void context (from
Simon Cozens <simon@othersideofthe.earth.li>) p4raw-id: //depot/perl@5600
Diffstat (limited to 'lib/Fatal.pm')
-rw-r--r--lib/Fatal.pm47
1 files changed, 37 insertions, 10 deletions
diff --git a/lib/Fatal.pm b/lib/Fatal.pm
index d033d62713..1496117c89 100644
--- a/lib/Fatal.pm
+++ b/lib/Fatal.pm
@@ -12,9 +12,15 @@ $Debug = 0 unless defined $Debug;
sub import {
my $self = shift(@_);
my($sym, $pkg);
+ my $void = 0;
$pkg = (caller)[0];
foreach $sym (@_) {
- &_make_fatal($sym, $pkg);
+ if ($sym eq ":void") {
+ $void = 1;
+ }
+ else {
+ &_make_fatal($sym, $pkg, $void);
+ }
}
};
@@ -42,11 +48,11 @@ sub fill_protos {
}
sub write_invocation {
- my ($core, $call, $name, @argvs) = @_;
+ my ($core, $call, $name, $void, @argvs) = @_;
if (@argvs == 1) { # No optional arguments
my @argv = @{$argvs[0]};
shift @argv;
- return "\t" . one_invocation($core, $call, $name, @argv) . ";\n";
+ return "\t" . one_invocation($core, $call, $name, $void, @argv) . ";\n";
} else {
my $else = "\t";
my (@out, @argv, $n);
@@ -56,7 +62,7 @@ sub write_invocation {
push @out, "$ {else}if (\@_ == $n) {\n";
$else = "\t} els";
push @out,
- "\t\treturn " . one_invocation($core, $call, $name, @argv) . ";\n";
+ "\t\treturn " . one_invocation($core, $call, $name, $void, @argv) . ";\n";
}
push @out, <<EOC;
}
@@ -67,21 +73,27 @@ EOC
}
sub one_invocation {
- my ($core, $call, $name, @argv) = @_;
+ my ($core, $call, $name, $void, @argv) = @_;
local $" = ', ';
- return qq{$call(@argv) || croak "Can't $name(\@_)} .
- ($core ? ': $!' : ', \$! is \"$!\"') . '"';
+ if ($void) {
+ return qq/(defined wantarray)?$call(@argv):
+ $call(@argv) || croak "Can't $name(\@_)/ .
+ ($core ? ': $!' : ', \$! is \"$!\"') . '"'
+ } else {
+ return qq{$call(@argv) || croak "Can't $name(\@_)} .
+ ($core ? ': $!' : ', \$! is \"$!\"') . '"';
+ }
}
sub _make_fatal {
- my($sub, $pkg) = @_;
+ my($sub, $pkg, $void) = @_;
my($name, $code, $sref, $real_proto, $proto, $core, $call);
my $ini = $sub;
$sub = "${pkg}::$sub" unless $sub =~ /::/;
$name = $sub;
$name =~ s/.*::// or $name =~ s/^&//;
- print "# _make_fatal: sub=$sub pkg=$pkg name=$name\n" if $Debug;
+ print "# _make_fatal: sub=$sub pkg=$pkg name=$name void=$void\n" if $Debug;
croak "Bad subroutine name for Fatal: $name" unless $name =~ /^\w+$/;
if (defined(&$sub)) { # user subroutine
$sref = \&$sub;
@@ -109,7 +121,7 @@ sub$real_proto {
local(\$", \$!) = (', ', 0);
EOS
my @protos = fill_protos($proto);
- $code .= write_invocation($core, $call, $name, @protos);
+ $code .= write_invocation($core, $call, $name, $void, @protos);
$code .= "}\n";
print $code if $Debug;
{
@@ -150,6 +162,21 @@ replaced. You may wrap both user-defined functions and overridable
CORE operators (except C<exec>, C<system> which cannot be expressed
via prototypes) in this way.
+If the symbol C<:void> appears in the import list, then functions
+named later in that import list raise an exception only when
+these are called in void context--that is, when their return
+values are ignored. For example
+
+ use Fatal qw/:void open close/;
+
+ # properly checked, so no exception raised on error
+ if(open(FH, "< /bogotic") {
+ warn "bogo file, dude: $!";
+ }
+
+ # not checked, so error raises an exception
+ close FH;
+
=head1 AUTHOR
Lionel.Cons@cern.ch