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.18';
4              
5 8     8   349744 use strict;
  8         51  
  8         283  
6 8     8   54 use warnings;
  8         19  
  8         386  
7 8     8   52 use Carp;
  8         22  
  8         604  
8 8     8   4438 use AnyEvent;
  8         31242  
  8         344  
9 8     8   76 use Scalar::Util qw(weaken);
  8         24  
  8         532  
10 8     8   2330 use Argon::Log;
  8         31  
  8         771  
11              
12              
13 8     8   106 use parent 'Exporter';
  8         22  
  8         73  
14              
15             our @EXPORT_OK = (
16             qw(K param interval),
17             );
18              
19              
20             sub K ($$;@) {
21 74     74 1 1809 my $name = shift;
22 74         143 my $self = shift;
23 74         170 my @args = @_;
24              
25 74         362 my $method = $self->can($name);
26              
27 74 50       229 unless ($method) {
28 0         0 croak "method $name not found";
29             }
30              
31 74         267 weaken $self;
32 74         220 weaken $method;
33              
34 74     56   1223 sub { $method->($self, @args, @_) };
  56         80695  
35             }
36              
37              
38             sub param ($\%;$) {
39 4     4 1 5945 my $key = shift;
40 4         8 my $param = shift;
41 4 100 66     22 if (!exists $param->{$key} || !defined $param->{$key}) {
42 3 100       11 if (@_ == 0) {
43 1         273 croak "expected parameter '$key'";
44             }
45             else {
46 2         4 my $default = shift;
47 2 50 33     19 return (ref $default && ref $default eq 'CODE')
48             ? $default->()
49             : $default;
50             }
51             }
52             else {
53 1         10 return $param->{$key};
54             }
55             }
56              
57              
58             sub interval (;$) {
59 3   50 3 1 3052 my $intvl = shift || 1;
60 3         9 my $count = 0;
61              
62             return sub {
63 7     7   468 my $reset = shift;
64              
65 7 100       19 if ($reset) {
66 1         3 $count = 0;
67 1         8 return;
68             }
69              
70 6         25 my $inc = log($intvl * ($count + 1));
71 6         10 ++$count;
72              
73 6         36 return $intvl + $inc;
74 3         133 };
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.18
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