File Coverage

blib/lib/Attempt.pm
Criterion Covered Total %
statement 30 30 100.0
branch 12 12 100.0
condition n/a
subroutine 6 6 100.0
pod 0 1 0.0
total 48 49 97.9


line stmt bran cond sub pod time code
1             package Attempt;
2              
3 5     5   207381 use Exporter;
  5         13  
  5         260  
4 5     5   28 use base qw(Exporter);
  5         9  
  5         389  
5              
6 5     5   28 use vars qw(@EXPORT $VERSION);
  5         14  
  5         519  
7             @EXPORT = qw(attempt);
8              
9 5     5   28 use strict;
  5         8  
  5         196  
10             #use warnings;
11              
12 5     5   28 use Carp qw(croak);
  5         7  
  5         1427  
13              
14             $VERSION = "1.01";
15              
16             =head1 NAME
17              
18             Attempt - attempt to run code multiple times
19              
20             =head1 SYNOPSIS
21              
22             use Attempt;
23              
24             # if the database goes away while we're using it, just try again...
25             attempt {
26              
27             my $dbh = DBI->connect("DBD::Mysql:foo", "mark", "opensaysme")
28             or die "Can't connect to database";
29             $dbh->{RaiseException} = 1;
30             $dbh->do("alter table items change pie pies int(10)");
31              
32             } tries => 3, delay => 2;
33              
34             =head1 DESCRIPTION
35              
36             Attempt creates a new construct for things that you might want to
37             attempt to do more than one time if they throw exceptions, because the
38             problems they throw exceptions to report might go away.
39              
40             Exports a new construct called C. The simplest way to use
41             C is to write attempt followed by a block of code to attempt
42             to run.
43              
44             attempt {
45             something_that_might_die();
46             };
47              
48             By default perl will attempt to run to run the code again without
49             delay if an exception is thrown. If on the second run an exception
50             is again thrown, that exception will be propogated out of the attempt
51             block as normal.
52              
53             The particulars of the run can be changed by passing parameters after
54             the code block. The C parameter effects the number of times the
55             code will attempt to be run. The C parameter determines how
56             often perl will wait - sleep - between runs.
57              
58             C can return values, and you can exit out of an attempt block
59             at any point with a return statement as you might expect. List and
60             scalar context is preserved though-out the call to the block.
61              
62             =cut
63              
64             sub attempt (&;@)
65             {
66 8     8 0 2178 my $code = shift;
67 8         23 my %args = @_;
68              
69 8         12 my @results;
70             my $result;
71              
72             # find out how many attempts we're going to take,
73             # defaulting to two.
74 8 100       33 my $tries = exists($args{tries}) ? $args{tries} : 2;
75              
76             # try while we've got tries left.
77 8         13 while (1)
78             {
79             # do we want a list?
80 18         39 my $wantarray = wantarray;
81              
82             # try running the code
83             eval
84 18         34 {
85 18 100       45 if ($wantarray)
86 1         4 { @results = $code->() }
87             else
88 17         63 { $result = $code->() }
89             };
90              
91             # return if we're sucessful
92 18 100       8338 return ($wantarray ? @results : $result )
    100          
93             unless $@;
94              
95             # we've used up a try
96 11         15 $tries--;
97 11 100       30 last if $tries < 1;
98              
99             # sleep if we need to
100 10 100       9006121 select undef, undef, undef, $args{delay}
101             if exists $args{delay};
102             }
103              
104             # got this far and didn't already return, so propogate the error
105 1         26 croak $@;
106             }
107              
108             =head1 AUTHOR
109              
110             Written by Mark Fowler Emark@twoshortplanks.comE
111              
112             Copryright Mark Fowler 2003. All Rights Reserved.
113              
114             This program is free software; you can redistribute it
115             and/or modify it under the same terms as Perl itself.
116              
117             =head1 BUGS
118              
119             Only respects list and scalar context, doesn't replicated
120             the more complicated forms of context that B supports.
121              
122             The caller isn't what you might expect from within the attempt
123             block (or rather, it is, but isn't what it would have been if
124             the block wasn't there)
125              
126             Bugs should be reported to me via the CPAN RT system.
127             L.
128              
129             =head1 SEE ALSO
130              
131             L, L
132              
133             =cut
134              
135             1;