Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re^3: eval to replace die?

by BrowserUk (Pope)
on Oct 04, 2010 at 13:35 UTC ( #863341=note: print w/ replies, xml ) Need Help??


in reply to Re^2: eval to replace die?
in thread eval to replace die?

Perhaps you'd be more comfortable with Tcl circa 1998.

No. I'm quite happy with Perl thank you.

You're the one who seems to want to turn Perl into Java.

One big drawback of string exceptions is that you have to parse strings to decide how to handle them. Parsing strings (especially to determine flow control) is fragile.

This is typical of your response to relatively simple problems. Throw yet another layer (or three) of complicated code on top, in an attempt to make the problems "go away".

Yes, error messages change occasionally.

Not often, but the recent addition to "Uninitialised value" is a ready exceptional hook upon which to hang your demagoguery. Despite that no one in their right mind is going to use exception handling to deal with an uninitialised variable(*). C'st la vie.

(*) Perhaps you'd offer us a worked example of how using Exception::Class to trap an uninitialised variable would have 'saved the day', when the variable name was added to the message?

We could then examine the basis of your justifictions; assess the impacts, pro's & con's of your suggested alternative; explore alternative alternatives.

Of course, you won't. Because you're a busy man with no time to explain your "wisdom", much less open it up to the challenge of open debate.

If you're performing an exact match, a substring match, or a regular expression, any change to the text of that message in a subsequent release of Perl 5 could change the way your code behaves.

So, the crux of this is that instead of the simplicity and clarity (both code and error reporting) of:

#! perl -slw use strict; sub divide { my( $e, $d ) = @_; return $e / $d; } my $result = eval{ divide( @ARGV ) } or die $@; print "Result: $result";

you're advising people to use (something like*):

(*)This doesn't actually work. Because I can't work out how to use the module. Because there are no simple, complete, working examples that I can find. Probably because it is so insanely complicated to use that simple, complete, working examples aren't possible!

#MyExceptions.pm package MyExceptions; use Exception::Class ( 'MyException', 'AnotherException' => { isa => 'MyException' }, 'YetAnotherException' => { isa => 'AnotherException', description => 'These exceptions are related to IPC' }, 'ExceptionWithFields' => { isa => 'YetAnotherException', fields => [ 'grandiosity', 'quixotic' ], alias => 'throw_fields', }, ); 1; ## Exceptions.pl #! perl -slw use strict; use MyExceptions; sub divide { my( $e, $d ) = @_; MyExceptions->throw( error => 'Divisor undefined' ) unless defined + $d; MyExceptions->throw( error => 'Divisor is zero' ) if $d == 0; return $e / $d; } # try my $result = eval { divide( @ARGV ) }; my $e; # catch if ( $e = Exception::Class->caught('MyException') ) { die 'You must supply two arguments' if $e->error eq 'Divisor undef +ined'; die 'The second argument must not be zero' if $e->error eq 'Diviso +r is zero'; die sprintf "Unanticipated exception: '%s' at \n%s\n", $e->error, +$e } else { $e = Exception::Class->caught(); ref $e ? $e->rethrow : die $e; }

If you are unable--or more likely, unwilling--to see all the ways that can go wrong. That this is even more dependant upon string comparisons. And all the addition problems you've created for the maintenance programmers to have to unwind, sift through and reverse engineer through all those extra layers, when it does go wrong. Then I guess they'll just end up reaping what you sow.

Even if you avoid comparing $e->error() to decide how to deal with the exceptions,

you are still relying upon MyException->caught( 'MyException' ),

which replies upon Exception::Class::Base->isa( 'MyException' ).

And what does isa() do that isn't subject to exactly the same error vectors a string compare?


There are times when exceptions are useful. But reaching for the insane complexity of modules like Exception::Class just in order to achieve "Java-esque"-ness; rather than something perlish-ly simple like Try::Tiny:

is madness. Java-envy of the worst kind.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.


Comment on Re^3: eval to replace die?
Select or Download Code
Re^4: eval to replace die?
by chromatic (Archbishop) on Oct 04, 2010 at 14:51 UTC
    And what does isa() do that isn't subject to exactly the same error vectors a string compare?

    It doesn't perform a regular expression match, for one. If you've never changed the text of an exception message and then had to change the regex of handlers, good. I have.

    The problem with Java isn't structured exceptions. It's one part "Wow, look at how awesome we can make a fragile hierarchy!" and two parts mandatory structured exceptions.

      It doesn't perform a regular expression match, for one.

      So now you are demonising regular expressions? Should we scrap regexes all together?

      If you've never changed the text of an exception message and then had to change the regex of handlers, good. I have.

      And you've never had to restructure your exceptions? I have.

      I say again, how is that different?

      Look at all the places in the Exception Class example I posted where the (same) name of the exception (class) is embedded inside a string.

      • Think about how many opportunities that creates for typos.

        Typos that are not even subjected to the rigours of syntax checking.

        By moving your error texts into the name-space hierarchy, you've just moved the problem elsewhere and wrapped it up in a heap of complexity.

        You've re-created the very problems that Abigail attempted to address with Inside Out objects. That of preventing strict from working by putting program "keywords" into hash keys. Stashes are just hashes.

        And along the way, thrown away a bunch of useful tools. Like regex.

        Which means you can no longer follow Postel's Prescription: "Be generous in what you accept, rigorous in what you emit", because (for example) you cannot use a regex with /i to ignore casing.

        Or just $@ =~ /^Uninitialised variable/ to match just the invariant part of the error.

      • And all the places in that example that need to be changed when you inevitably have to re-structure your exception handling.

        You've just quadrupled the number of places in the code you need to change. And in the process added 3 more layers; 5 more dependencies; and a crap load more code into the bargain.

        There is an undeniable truth that says: more code == more bugs. And you've just added a bunch more complicated code trying to avoid a situation that can be trivially dealt with without it.

      Maybe those can be avoided by using Exception::Class better? If so, please enlighten us with an example.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Should we scrap regexes all together?

        How do you go from "Converting structured information to strings, then using regular expressions to attempt to extract structured information is fragile" to "Don't use regular expressions"?

        Or just $@ =~ /^Uninitialised variable/ to match just the invariant part of the error.

        Invariants often aren't. See also theory's comment about localizing Bricolage.

        And you've never had to restructure your exceptions?

        Of course I have. Code changes. Changing regular expressions used for control flow because data has changed is different.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://863341]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (14)
As of 2014-07-31 19:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (251 votes), past polls