SlideShare une entreprise Scribd logo
1  sur  47
Télécharger pour lire hors ligne
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
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
Perl Sucks!
                              (and what to do about it)




                                           Image courtesy of Mark Fowler


                          YAPC::EU 2007 – Vienna

Tuesday, 11 August 2009
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
eval {};
                           sucks


Tuesday, 11 August 2009
eval {};
                           sucks


Tuesday, 11 August 2009
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
“But Perl already has
                          exception handling”
                           Lots of Exception::* and Error::* modules




Tuesday, 11 August 2009
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
I want the Moon on a Stick
Tuesday, 11 August 2009
I want the Moon on a Stick
Tuesday, 11 August 2009
Exceptions in JavaScript

                          try {
                            someCallThatDies();
                          }
                          catch (e if e instanceof Error) {}
                          catch (f if f.length < 10) {}
                          catch (g) { /* otherwise */ }




Tuesday, 11 August 2009
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
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
That’s a lot to
                          write every time
                               Not very DRY




Tuesday, 11 August 2009
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
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
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
TryCatch.pm
                          use TryCatch;
                          try {
                            some_call_that_dies();
                          }
                          catch (Error $e) {}
                          catch ($f where {length < 10}) {}
                          catch ($g) {} # otherwise




Tuesday, 11 August 2009
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
Try syntax

                    • try keyword
                    • Followed by a block
                    • That was easy :)


Tuesday, 11 August 2009
Catch syntax

                    • catch keyword
                    • Followed by an optional signature:
                          (MyError $e where { } )

                    • Followed by a block.

Tuesday, 11 August 2009
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
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
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
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
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
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
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
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
xkcd.com




                          Implementation
                          Here Be (anthropomorphic) Dragons
Tuesday, 11 August 2009
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
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
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
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
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
Using Devel::Declare
                    • When perl parses
                          catch ($e) { my $foo = …

                    • Sees catch as a OP_CONST




Tuesday, 11 August 2009
Using Devel::Declare
                    • When perl parses
                          catch ($e) { my $foo = …

                    • Calls PL_check[OP_CONST]




Tuesday, 11 August 2009
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
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
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
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
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
In short, lots of scary
                                    XS.
Tuesday, 11 August 2009
use TryCatch;

                try {
                  some_call_that_dies();
                }
                catch (Error $e) {}
                catch ($f where {length < 10}) {}
                catch ($g) {} # otherwise




Tuesday, 11 August 2009
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
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

Contenu connexe

En vedette

Textual analysis of catch me if you can
Textual analysis of catch me if you canTextual analysis of catch me if you can
Textual analysis of catch me if you canpatrickmetry
 
CATCH US IF YOU CAN - Anna Isha
CATCH US IF YOU CAN - Anna IshaCATCH US IF YOU CAN - Anna Isha
CATCH US IF YOU CAN - Anna IshaAnna Isha
 
Top 10 Most Eaten Foods In The World
Top 10 Most Eaten Foods In The WorldTop 10 Most Eaten Foods In The World
Top 10 Most Eaten Foods In The WorldEason Chan
 
Oscars 2016: Winners and Highlights
Oscars 2016: Winners and  HighlightsOscars 2016: Winners and  Highlights
Oscars 2016: Winners and Highlightsmaditabalnco
 
Can We Assess Creativity?
Can We Assess Creativity?Can We Assess Creativity?
Can We Assess Creativity?John Spencer
 

En vedette (6)

Textual analysis of catch me if you can
Textual analysis of catch me if you canTextual analysis of catch me if you can
Textual analysis of catch me if you can
 
CATCH US IF YOU CAN - Anna Isha
CATCH US IF YOU CAN - Anna IshaCATCH US IF YOU CAN - Anna Isha
CATCH US IF YOU CAN - Anna Isha
 
LONDON
LONDONLONDON
LONDON
 
Top 10 Most Eaten Foods In The World
Top 10 Most Eaten Foods In The WorldTop 10 Most Eaten Foods In The World
Top 10 Most Eaten Foods In The World
 
Oscars 2016: Winners and Highlights
Oscars 2016: Winners and  HighlightsOscars 2016: Winners and  Highlights
Oscars 2016: Winners and Highlights
 
Can We Assess Creativity?
Can We Assess Creativity?Can We Assess Creativity?
Can We Assess Creativity?
 

Dernier

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Dernier (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

Catch Me If You Can: Sugary Exception Handling in Perl

  • 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