File Coverage

blib/lib/Try/Catch.pm
Criterion Covered Total %
statement 62 62 100.0
branch 34 34 100.0
condition 4 6 66.6
subroutine 9 9 100.0
pod 3 3 100.0
total 112 114 98.2


line stmt bran cond sub pod time code
1             package Try::Catch;
2 13     13   271488 use strict;
  13         28  
  13         514  
3 13     13   61 use warnings;
  13         16  
  13         382  
4 13     13   56 use Carp;
  13         22  
  13         1035  
5 13     13   8886 use Data::Dumper;
  13         110412  
  13         1356  
6             $Carp::Internal{+__PACKAGE__}++;
7 13     13   96 use base 'Exporter';
  13         19  
  13         6975  
8             our @EXPORT = our @EXPORT_OK = qw(try catch finally);
9             our $VERSION = '0.0.5';
10            
11             sub _default_cache {
12 4     4   770 croak $_[0];
13             }
14            
15             sub try(&;@) {
16 63     63 1 421 my $wantarray = wantarray;
17 63         94 my $try = shift;
18 63         94 my $caller = pop;
19 63         81 my $finally = pop;
20 63         76 my $catch = pop;
21            
22 63 100 66     408 if (!$caller || $caller ne __PACKAGE__){
23 1         92 croak "syntax error after try block \n" .
24             "usage : \n" .
25             "try { ... } catch { ... }; \n" .
26             "try { ... } finally { ... }; \n" .
27             "try { ... } catch { ... } finally { ... }; ";
28             }
29            
30             #sane behaviour is to throw an error
31             #if there is no catch block
32 62 100       139 if (!$catch){
33 11         44 $catch = \&_default_cache;
34             }
35            
36 62         78 my @ret;
37 62         108 my $prev_error = $@;
38 62         145 my $fail = not eval {
39 62         75 $@ = $prev_error;
40 62 100       146 if (!defined $wantarray) {
    100          
41 51         129 $try->();
42             } elsif (!$wantarray) {
43 7         19 $ret[0] = $try->();
44             } else {
45 4         14 @ret = $try->();
46             }
47 22         1051722 return 1;
48             };
49            
50 58         4048 my $error = $@;
51 58 100       235 my @args = $fail ? ($error) : ();
52            
53 58 100       649 if ($fail) {
54 36         43 my $ret = not eval {
55 36         51 $@ = $prev_error;
56 36         62 local $_ = $args[0];
57 36         72 for ($_){
58 36 100       79 if (!defined $wantarray) {
    100          
59 30         704 $catch->(@args);
60             } elsif (!$wantarray) {
61 4         13 $ret[0] = $catch->(@args);
62             } else {
63 2         482 @ret = $catch->(@args);
64             }
65 25         6373 last; ## seems to boost speed by 7%
66             }
67 26         916 return 1;
68             };
69            
70 36 100       744 if ($ret){
71 10 100       582 $finally->(@args) if $finally;
72 10         5488 croak $@;
73             }
74             }
75            
76 48         103 $@ = $prev_error;
77 48 100       164 $finally->(@args) if $finally;
78 47 100       5530 return $wantarray ? @ret : $ret[0];
79             }
80            
81             sub catch(&;@) {
82 57 100   57 1 8495 croak 'Useless bare catch()' unless wantarray;
83 54 100       176 if (@_ > 1){
84 18 100 66     183 croak "syntax error after catch block - maybe a missing semicolon"
85             if !$_[2] || $_[2] ne __PACKAGE__;
86             } else {
87 36         995 return ( shift, undef, __PACKAGE__);
88             }
89 17         99 return (@_);
90             }
91            
92             sub finally(&;@) {
93 33 100   33 1 7800 croak 'Useless bare finally()' unless wantarray;
94 30 100       107 if (@_ > 1) {
95 1         113 croak "syntax error after finally block - maybe a missing semicolon";
96             }
97 29         3634 return ( shift, __PACKAGE__ );
98             }
99            
100             1;
101            
102             __END__