File Coverage

blib/lib/Argon/Util.pm
Criterion Covered Total %
statement 48 49 97.9
branch 8 10 80.0
condition 4 8 50.0
subroutine 12 12 100.0
pod 3 3 100.0
total 75 82 91.4


line stmt bran cond sub pod time code
1             package Argon::Util;
2             # ABSTRACT: Utilities used in Argon classes
3             $Argon::Util::VERSION = '0.17';
4              
5 8     8   173251 use strict;
  8         32  
  8         280  
6 8     8   50 use warnings;
  8         20  
  8         268  
7 8     8   45 use Carp;
  8         16  
  8         515  
8 8     8   3442 use AnyEvent;
  8         22973  
  8         302  
9 8     8   62 use Scalar::Util qw(weaken);
  8         18  
  8         433  
10 8     8   1551 use Argon::Log;
  8         21  
  8         1077  
11              
12              
13 8     8   53 use parent 'Exporter';
  8         19  
  8         53  
14              
15             our @EXPORT_OK = (
16             qw(K param interval),
17             );
18              
19              
20             sub K ($$;@) {
21 74     74 1 1516 my $name = shift;
22 74         136 my $self = shift;
23 74         170 my @args = @_;
24              
25 74         373 my $method = $self->can($name);
26              
27 74 50       245 unless ($method) {
28 0         0 croak "method $name not found";
29             }
30              
31 74         289 weaken $self;
32 74         219 weaken $method;
33              
34 74     56   1135 sub { $method->($self, @args, @_) };
  56         81382  
35             }
36              
37              
38             sub param ($\%;$) {
39 4     4 1 4388 my $key = shift;
40 4         6 my $param = shift;
41 4 100 66     19 if (!exists $param->{$key} || !defined $param->{$key}) {
42 3 100       9 if (@_ == 0) {
43 1         206 croak "expected parameter '$key'";
44             }
45             else {
46 2         5 my $default = shift;
47 2 50 33     14 return (ref $default && ref $default eq 'CODE')
48             ? $default->()
49             : $default;
50             }
51             }
52             else {
53 1         12 return $param->{$key};
54             }
55             }
56              
57              
58             sub interval (;$) {
59 3   50 3 1 1647 my $intvl = shift || 1;
60 3         10 my $count = 0;
61              
62             return sub {
63 7     7   315 my $reset = shift;
64              
65 7 100       16 if ($reset) {
66 1         2 $count = 0;
67 1         8 return;
68             }
69              
70 6         21 my $inc = log($intvl * ($count + 1));
71 6         9 ++$count;
72              
73 6         29 return $intvl + $inc;
74 3         122 };
75             }
76              
77             1;
78              
79             __END__
80              
81             =pod
82              
83             =encoding UTF-8
84              
85             =head1 NAME
86              
87             Argon::Util - Utilities used in Argon classes
88              
89             =head1 VERSION
90              
91             version 0.17
92              
93             =head1 DESCRIPTION
94              
95             Utility functions used in Argon classes.
96              
97             =head1 EXPORTS
98              
99             No subroutines are exported by default.
100              
101             =head1 SUBROUTINES
102              
103             =head2 K
104              
105             Creates a callback function that calls a method on an object instance with
106             arbitrary arguments while preventing circular references from closing over the
107             method or object instance itself.
108              
109             my $callback = K('method_name', $self, $arg1, $arg2, ...);
110              
111             =head2 param
112              
113             Extracts a parameter from an argument hash.
114              
115             sub thing{
116             my ($self, %param) = @_;
117             my $foo = param 'foo', %param, 'default'; # equivalent: $param{foo} // 'default';
118             my $bar = param 'bar', %param; # equivalent: $param{bar} // croak "expected parameter 'bar'";
119             }
120              
121             =head2 interval
122              
123             Returns a code ref that, when called, returns an increasing interval value to
124             simplify performing a task using a logarithmic backoff. When the code ref is
125             called with an argument (a truthy one), the backoff will reset back to the
126             original argument.
127              
128             my $intvl = interval 5;
129              
130             until (some_task_succeeds()) {
131             sleep $intvl->();
132             }
133              
134             =head1 AUTHOR
135              
136             Jeff Ober <sysread@fastmail.fm>
137              
138             =head1 COPYRIGHT AND LICENSE
139              
140             This software is copyright (c) 2017 by Jeff Ober.
141              
142             This is free software; you can redistribute it and/or modify it under
143             the same terms as the Perl 5 programming language system itself.
144              
145             =cut