At 07:58 PM 8/22/00 +0200, Markus Peter wrote:
>What I was actually requesting was a small pragma which simply turns off
>all fatality, in the whole program, similar to what $SIG{__DIE__}
>currently is able to do,
Are you sure? $SIG{__DIE__} cannot prevent the program terminating once it
returns.
> without the need to span a try/catch block across my whole main program
> - I simply do not like the look and feel of that. Even though this has
> global effects, it's not necessarily evil, we should only ensure that it
> cannot be used from within a .pm
I don't think you should try that (limiting to a .pm) even if you
could. One person's .pm is another person's user code.
From the reactions on this thread so far I am wondering whether the
message I sent out about it when it had a different name got
through. Relevant excerpt:
Well, you could certainly have a pragma that makes throw set $! to the
message and does a return undef. But that will only return from the
current subroutine; there could be a bunch of module subroutines between
that one and the module user. Asking module programmers to keep straight
two possible flows of control in error situations, no less, is asking for
trouble. If you think it can be made easier, can you show an example?
I think all we can do is encourage module authors to provide both styles
with a switch to select them by (API decided by module author). The
reality will be that some module authors will do that, some will do
exception handling everyhere, some will do error return everywhere, and
some will do a mixture of both in the same module. Which, btw, is what we
have right now. Grep the core pm's for 'croak' and 'die'. Take a look at
the (F)s in perldiag. Notice that division doen't return undef when the
dividend is 0 :-)
I just looked at non-core modules and the usage of croak and die is even
higher. So IMHO it is already unreasonable to expect to be able to program
completely in a return-code handling style.
Now, I do not want that to detract completely from Chaim's point, which is
well taken. I too would rather say
my $fh = open $filename or die "Couldn't copy source: $!"
than
my $fh; try { $fh = open $filename } catch { die "Couldn't copy
source: ", $@->syserr }
I *know* that it sucks, linguistically, to convolve error notification with
the return data space, and then to pass additional information out-of-band
in a global variable. It also happens to be darn readable. I don't want
to give it up any more than you, Chaim.
I think I have an answer. We should be able to take care of the core by
using Fatal.pm; so if a program wants core functions to set $! and return
anyway, that will be the default. This means that some core functions that
currently die will need their interfaces reworked. I actually see nothing
wrong in division returning undef for a dividend of 0. It's just as easy
to check as doing an eval.
Module authors should also be able to take advantage of Fatal.pm. "use
Fatal" should set something that can be checked by any programmer (heck,
that doesn't even have to be restricted to module authors; the creator of
an insanely large program might do it). The programmer can use this to
decide whether to throw an exception or return. [Bennett, this impacts RFC
70 in IMHO a good way; you may consider expanding its scope to be not just
binding on the core, but advisory for everything else. Perhaps suggest an
interface whereby user code can see what the setting is.]
***But it's entirely up to each programmer whether or not they use
Fatal-checking*** This is the Perl way anyway.
And guess what? Some people will do it, some people won't; some people
will throw exceptions everywhere, some won't, and some will do a
mixture. Just like now. You want to use a module, you read its interface
documentation and if it throws, you catch; or you use something else.
Maybe one day we can make a CPANTS [Comprehensive Perl Archive Network
Testing Service, under development] test for Fatal-checking, and authors
who do it will get better karma.
--
Peter Scott
Pacific Systems Design Technologies