Nicholas Clark wrote:
> 
> my $f = open $file or die "can't open $file";
>
> is troublesome. It doesn't report *why* the file can't be opened.
>
> [...]  *flexible* exceptions are needed

The first version of RFC 88 didn't care what exception objects
were, but discussions in the errors mailing list convinced us that
we should define a base class for exceptions, to guarantee that
certain things are there.  Developers can of course define derived
classes to extend what exceptions can know/do, and the RFC 88 syntax
allows these properties to be used to write conditional catches and
fancier unwinding traceback reports.  An example of such a derived
exception class is included in RFC 88.  See the comments on your
IO layer problem below.

Jarkko Hietaniemi wrote:
> 
> Nicholas Clark wrote:
> > 
> > Jarkko would really like
> >
> >   print "Foo\n";
> >
> > in a void context to behave as
> >
> >   print "Foo\n" or die $!;
> 
> Not just basic I/O but anything 'system': pipe(), system(),
> opendir(), mkdir(), chdir(), fork(), socket(), and so on.

RFC 88 can be used as an exception handling mechanism independent of
whether or not the core uses exceptions to signal errors (whether
in system calls, math operations, or -gasp- the parser).  If the
core does use exceptions to signal errors (whether or not controlled
by a pragma), then RFC 88 says it punts to RFC 80 on the matter of
the details of the derived exception class to be used as the base
for core exceptions.  RFC 88 only requires that the core exceptions
inherit from the base class.  RFC 80 is free to define its own class
hierarchy (things like Exception::CORE::IO::NotFound), and it's own
rules for what information is contained in an exception's message,
and how it is formatted.  These message-building operations can be
overridden for various sections of the core exception class hierarchy.

RFC 88 shows a simple way to do pragma-based conversion of error
modes at the core API (in which case no exception objects, in
the OO sense, need be handled by the bulk of the core), and a simple
way to support both exception-based and return-code-based error
handling modes based on the dynamic value of a pragma, in module
APIs.  Personally, I think we should just use exceptions to signal
errors, and then (1) there's no need for this pragma-based duality,
and (2) you don't have to worry about forgetting to check return
codes (thereby mis-handling failures).

Nicholas Clark wrote:
> 
> I'm experimenting with PerlIO layers. If a layer decides it can't
> honour an open due to a reason not covered by errno, it has no way
> of reporting this.

If exceptions are being used to signal errors, your layer can simply
stack an exception that is an instance of a class that inherits
from, say, Exception::CORE::Layer, and those exceptions can track
whatever sort of error-related data you want.  Something like this:

    package MyLayer;

    sub OperationFoo
    {
        try {
            code that performs operations using layer below me
            }
        catch {
            throw Exception::CORE::Layer::Me::CantFoo
                "additional information based on my layer",
                other => "info", from => "me too", ...;
            }
        }

Now, if things go bad in the layer below, when somebody gets
around to telling the user about the unwinding, $@->show will
include messages like the following:

    ...
    Exception::CORE::Layer::Me::CantFoo: additional information
        based on my layer.
    Exception::CORE::Layer::Low::CantBar: additional information
        from lower layer.
    ...

You effectively have C< map { $_->{errno} } @@ > available for
all the exceptions raised since the last time an exception was
cleanly caught.

Nicholas Clark wrote:
> 
> I think that it would be nice in 5.8 to (optionally on some
> pragma?) make print, close and a few others in void context croak.
> It would actually make writing perl scripts easier. You'd know
> when your disk became full (or you went over quota), albeit in
> with a messy error.  OK, script crashing with an uncaught
> exception isn't nice, but it's nicer than silently losing data
> IMHO.

RFC 88 says, in support of the notion of using exeptions to signal
errors, "How many of us check for IO failures after prints? And if
you're writing a simple program you wouldn't want to have to, but
you would want the program to shut down after a failure if you don't
check."  Also, since you're not returning error codes any more, the
matter of the void context is moot: failures always throw.

Yours, &c, Tony Olekshy

Reply via email to