Catch Me If You Can: Sugary Exception Handling in Perl

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

1 comments

Comments 1 - 1 of 1 previous next Post a comment

  • + zarthustra7 zarthustra7 1 month ago
    Are you familiar with Exception::Class? Check my blog: codeunquote.blogger.com where I have a 5-part series on exception handling starting with basics and ending with Best Practices.

    Exception Handling with Exception::Class is a whole new experience. I have made it part of the coding standards at my firm and it has been a substantial factor in improving code quality.

    Cheers!
Post a comment
Embed Video
Edit your comment Cancel

2 Favorites

Catch Me If You Can: Sugary Exception Handling in Perl - Presentation Transcript

  1. EXCEPTION HANDLING IN PERL catch me if you can YAPC EU 2009 = ASH BERLIN ‹ %DEVEL DECLARE / SCOPE UPPER ‹ eASH BERLIN aASH BERLIN ½ MST < FLORIAN RAGWITZ / VINCENT PIT £MARK FOWLER / THE O’REILLY CAMEL Tuesday, 11 August 2009
  2. Catch Me If You Can: Sugary exception handling with TryCatch.pm Ash Berlin YAPC::EU 2009 – Lison A.K.A The please don’t sue me Title Tuesday, 11 August 2009
  3. Perl Sucks! (and what to do about it) Image courtesy of Mark Fowler YAPC::EU 2007 – Vienna Tuesday, 11 August 2009
  4. Perl Sucks? • Of course it does, it’s software • Installing Modules is hard • Perl programs are just scripts • Its Exception handling is hateful Tuesday, 11 August 2009
  5. eval {}; sucks Tuesday, 11 August 2009
  6. eval {}; sucks Tuesday, 11 August 2009
  7. eval sucks • Sucky syntax • Easy to get (subtly) wrong. • return doesn’t work as expected • eval BLOCK vs eval EXPR • $@ is global Tuesday, 11 August 2009
  8. “But Perl already has exception handling” Lots of Exception::* and Error::* modules Tuesday, 11 August 2009
  9. None of them Perfect • Some are just an exception framework • Good; doesn’t solve catching problem • Catching errors shouldn’t be hard Tuesday, 11 August 2009
  10. I want the Moon on a Stick Tuesday, 11 August 2009
  11. I want the Moon on a Stick Tuesday, 11 August 2009
  12. Exceptions in JavaScript try { someCallThatDies(); } catch (e if e instanceof Error) {} catch (f if f.length < 10) {} catch (g) { /* otherwise */ } Tuesday, 11 August 2009
  13. The same in Perl eval { some_call_that_dies(); }; if (blessed($@) && $@->isa(‘Error’)) { my $e = $@; } elsif (len($@) < 10 ) { my $f = $@; } elsif ($@) { my $g = $@; } Tuesday, 11 August 2009
  14. The same in Perl Done properly { local $@; eval { some_call_that_dies(); }; if (my $_e = $@) { if (blessed($_e) && $_e->isa(‘Error’)) { my $e = $_e; } elsif (len($_e) < 10 ) { my $f = $_e; } else { my $g = $_e; } } } Tuesday, 11 August 2009
  15. That’s a lot to write every time Not very DRY Tuesday, 11 August 2009
  16. Using Error.pm use Error qw(:try); try { some_call_that_dies(); } catch Error with { my $e = shift; } Looking good so far… Tuesday, 11 August 2009
  17. Using Error.pm use Error qw(:try); try { some_call_that_dies(); } catch Error with { my $e = shift; } otherwise { my $f = shift; if (length($f) < 10) { } else { my $g = $f; } } Less good :( Tuesday, 11 August 2009
  18. Problems with Error.pm • (Not to single it out as bad) • Its Exception Object class • AND try/catch implementations • sub {} closures are slow • Speed for error free path is important Tuesday, 11 August 2009
  19. TryCatch.pm use TryCatch; try { some_call_that_dies(); } catch (Error $e) {} catch ($f where {length < 10}) {} catch ($g) {} # otherwise Tuesday, 11 August 2009
  20. TryCatch syntax • try must be followed by a block • Followed by zero or more catch clauses • catch may be followed by a signature • catch must also be followed by a block Tuesday, 11 August 2009
  21. Try syntax • try keyword • Followed by a block • That was easy :) Tuesday, 11 August 2009
  22. Catch syntax • catch keyword • Followed by an optional signature: (MyError $e where { } ) • Followed by a block. Tuesday, 11 August 2009
  23. Catch Sig syntax (MyError $e where { } ) • MyError is any valid Moose type constraint • Optional • Uses MooseX::Types for preference • Else falls back to Moose’s string parsing • Never quoted, always bare • Example: Str|ArrayRef[MyError] Tuesday, 11 August 2009
  24. Catch Sig syntax (MyError $e where { } ) • $e is the variable name for the error • Will be created as “my $e” in the block • A variable name is required Tuesday, 11 August 2009
  25. Catch Sig syntax (MyError $e where { } ) • Constraint (not type constraint) • $_ is the error being tested. • Much like grep or map, return truthy value • PPI used to just get ‘everything in {}’ Tuesday, 11 August 2009
  26. Syntax Notes • try can be nested as deep as you like • You can use return to exit the sub. • No finally.Yet. It’s on my TODO Tuesday, 11 August 2009
  27. TryCatch example sub foo { try { die MyError->new($_[0]) if $_[1] eq “class”; die $_[0] if $_[1] eq “plain”; return “value”; } catch (MyError $e) { } catch ($e where { /No Cheese!/ }) { } catch ($e) { } # otherwise } Tuesday, 11 August 2009
  28. TryCatch example sub foo { This will return a value from try { foo, not just the try/eval die MyError->new($_[0]) if $_[1] eq “class”; i.e. use return natually die $_[0] if $_[1] eq “plain”; return “value”; } catch (MyError $e) { } catch ($e where { /No Cheese!/ }) { } catch ($e) { } # otherwise } Tuesday, 11 August 2009
  29. TryCatch example sub foo { Moose type constraints try { handle the “is this a blessed die MyError->new($_[0]) object” and similar checks if $_[1] eq “class”; die $_[0] if $_[1] eq “plain”; return “value”; } catch (MyError $e) { } catch ($e where { /No Cheese!/ }) { } catch ($e) { } # otherwise } Tuesday, 11 August 2009
  30. TryCatch example sub foo { If this wasn’t here, and the try { plain error was thrown, it die MyError->new($_[0]) would get re-thrown. if $_[1] eq “class”; die $_[0] if $_[1] eq “plain”; return “value”; } catch (MyError $e) { } catch ($e where { /No Cheese!/ }) { } catch ($e) { } # otherwise } Tuesday, 11 August 2009
  31. xkcd.com Implementation Here Be (anthropomorphic) Dragons Tuesday, 11 August 2009
  32. Source Filters • Have to look through the entire source • And only change the bits they want. • Perl is notoriously hard to parse • Can cause odd bugs: Tuesday, 11 August 2009
  33. Source Filters package ShootMeInTheHead; use Moose; use Switch; sub foo {   my ($variable) = @_;   return $variable + 1; } sub bar {   my ($variable) = @_;   return $variab1e + 1; Global symbol "$variab1e" requires } explicit package name at line 18. } Tuesday, 11 August 2009
  34. Source Filters package ShootMeInTheHead; use Moose; use Switch; # load switch statement sub foo {   my ($variable) = @_;   return $variable + 1; } sub bar {   my ($variable) = @_;   return $variab1e + 1; Global symbol "$variab1e" requires } explicit package name at line 18. } Tuesday, 11 August 2009
  35. Source Filters package ShootMeInTheHead; use Moose; use Switch; # load switch statement sub foo {   my ($variable) = @_;   return $variable + 1; } sub bar {   my ($variable) = @_;   return $variab1e + 1; Global symbol "$variab1e" requires } explicit package name at line 14. } Tuesday, 11 August 2009
  36. Devel::Declare • Lets you change the source Perl is about to compile • Like a source filter • But far less fragile. • Key-hole source filter effect. Tuesday, 11 August 2009
  37. Using Devel::Declare • When perl parses catch ($e) { my $foo = … • Sees catch as a OP_CONST Tuesday, 11 August 2009
  38. Using Devel::Declare • When perl parses catch ($e) { my $foo = … • Calls PL_check[OP_CONST] Tuesday, 11 August 2009
  39. Using Devel::Declare • When perl parses catch ($e) { my $foo = … • Calls PL_check[OP_CONST] • Devel::Declare hooks this • And calls back into perl code Tuesday, 11 August 2009
  40. Using Devel::Declare • When perl parses catch ($e) { my $foo = … • Calls PL_check[OP_CONST] • Devel::Declare lets us change this into… catch; { if (my $e = $@) { my $foo = … Tuesday, 11 August 2009
  41. Using Devel::Declare • TryCatch doesn’t quite produce that code • But it shows how things work • Also uses B::Hooks::OP::{Check,PPaddr} to solve the return problem Tuesday, 11 August 2009
  42. The return problem • Simple: sub foo { eval { return $val }; 1} • Would be nice if it returned from foo • vincent++ # Scope::Upper • unwind HERE, @values; Tuesday, 11 August 2009
  43. The return problem • Typing return would be better than unwind • Install an extra PL_check hook on OP_RETURN • And install a custom op handler • Makes return inside try behave like unwind Tuesday, 11 August 2009
  44. In short, lots of scary XS. Tuesday, 11 August 2009
  45. use TryCatch; try { some_call_that_dies(); } catch (Error $e) {} catch ($f where {length < 10}) {} catch ($g) {} # otherwise Tuesday, 11 August 2009
  46. use TryCatch; try ;{ local $@; eval { some_call_that_dies(); }; $TryCatch::Error = $@; } if ($TryCatch::Error) { if (TryCatch->check_tc('Error')){ my $e = $TryCatch::Error; } elsif (do {local $_ = $TryCatch::Error; length($_) < 10 }) { my $f = $TryCatch::Error; } elsif (1){ my $g = $TryCatch::Error; } # otherwise else { $@ = $TryCatch::Error; die } } Tuesday, 11 August 2009
  47. hu∙bris noun excessive pride or self-confidence. • (in Greek tragedy) excessive pride toward or defiance of the gods, leading to nemesis. DERIVATIVES hu∙bris∙tic adjective ORIGIN Greek. Ash Berlin <ash@cpan.org> Questions? Tuesday, 11 August 2009

+ Ash BerlinAsh Berlin, 3 months ago

custom

1004 views, 2 favs, 1 embeds more stats

Exception handling in perl is currenlty far from pe more

More info about this document

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Go to text version

  • Total Views 1004
    • 1003 on SlideShare
    • 1 from embeds
  • Comments 1
  • Favorites 2
  • Downloads 53
Most viewed embeds
  • 1 views on http://www.slideshare.net

more

All embeds
  • 1 views on http://www.slideshare.net

less

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

Cancel
File a copyright complaint
Having problems? Go to our helpdesk?

Categories