On Fri, Apr 9, 2010 at 1:54 AM, Ovid
<[email protected]>wrote:
> (Javaesque psuedo-code):
>
> try {
> customer.read();
> }
> catch ( Exception::IO::NotFound e ) { ... }
> catch ( Exception::IO::CantOpen e ) { ... }
> catch ( Exception::IO::CantRead e ) { ... }
> catch ( Exception::IO e ) { ... }
> catch ( Exception e ) {
> panic("I don't know what type of exception I have!" . e);
> }
>
> Yeah, the example is overkill :)
>
> The point here is that you try more specific exceptions first and drill
> down to less specific ones, including a "catch-all" exception. However,
> what happens if you get rid of the "NotFound", "CantOpen" and "CantRead"? If
> the exception thrown is one of those types and assuming they're really
> subclasses of Exception::IO, then the "Exception::IO" catch will catch them
> rather the incorrectly falling through to the panic. If these were merely
> shoved in a hash, you'd have to try to fall back to parsing either the
> messages (or the key) to figure out that you don't really have a panic.
>
I've never understood what's wrong with using string exceptions for this
kind of thing. Maintaining a discipline about properly dieing is required
both ways, and
defined ($nextline = <INPUT>) or die "IO CANTREAD: eof on INPUT?"'
seems more concise than abstracting an exception type hierarchy behind a
class hierarchy only to unabstract it later:
eval {
$customer->read(); 1
} or do {{ # double openers to create block to last out of
my $e = $@;
$e =~ m/^io notfound/i and do { ...; last };
$e =~ m/^io CantOpen/i and do { ... ; last };
$e =~ m/^io CantRead/i and do { ... ; last };
$e =~ m/^io /i and do { ... ; last };
die "$e UNEXPECTED"; # filename, line number, newline added by die
}};
Either way, you still need to maintain the meaning of the string prefixes or
the various exception types in a project-wide data dictionary.
I don't want to start (or restart) some kind of big argument; my
understanding is that coders coming from a Java background simply prefer to
use classes for everything.