File Coverage

inc/My/Module/Recommend/Any.pm
Criterion Covered Total %
statement 28 57 49.1
branch 1 18 5.5
condition 1 3 33.3
subroutine 9 15 60.0
pod 4 4 100.0
total 43 97 44.3


line stmt bran cond sub pod time code
1             package My::Module::Recommend::Any;
2              
3 1     1   11 use 5.006002;
  1         2  
4              
5 1     1   3 use strict;
  1         1  
  1         12  
6 1     1   2 use warnings;
  1         1  
  1         36  
7              
8 1     1   3 use Carp;
  1         1  
  1         58  
9 1     1   3 use Exporter qw{ import };
  1         1  
  1         60  
10              
11             our $VERSION = '0.133';
12              
13             our @EXPORT_OK = qw{ __any };
14              
15 1     1   4 use constant ARRAY_REF => ref [];
  1         1  
  1         64  
16              
17 1     1   3 use constant RECOMMEND_TEMPLATE_SINGLE => " * %s is not available.\n";
  1         1  
  1         55  
18 1     1   4 use constant RECOMMEND_TEMPLATE_MULTI => " * None of %s is available.\n";
  1         1  
  1         523  
19              
20             sub __any {
21 0     0   0 my ( @args ) = @_;
22 0         0 return __PACKAGE__->new( @args );
23             }
24              
25             sub new {
26 1     1 1 3 my ( $class, @modules ) = @_;
27 1 50       3 @modules > 1
28             or croak 'Must specify at least one module and a message';
29 1         2 my $msg = pop @modules;
30 1         9 $msg =~ s/ ^\s* / /smxg;
31              
32 1   33     11 return bless {
33             modules => \@modules,
34             message => $msg,
35             }, ref $class || $class;
36             }
37              
38             sub check {
39 0     0 1   my ( $self ) = @_;
40 0           my @missing;
41 0           foreach my $m ( $self->modules() ) {
42 0 0         $self->__is_module_available( $m )
43             and return;
44 0           push @missing, $m;
45             }
46 0           return @missing;
47             }
48              
49             sub __is_module_available {
50 0     0     my ( undef, $m ) = @_;
51 0 0         my ( $mod, $ver ) = ARRAY_REF eq ref $m ? @{ $m } : ( $m );
  0            
52 0           my @eval = ( "require $mod;" );
53 0 0         defined $ver
54             and push @eval, "$mod->VERSION( $ver );";
55 0 0         eval "@eval 1;"
56             and return $m;
57 0           return;
58             }
59              
60             sub modules {
61 0     0 1   my ( $self ) = @_;
62             return (
63 0 0         map { ARRAY_REF eq ref $_ ? $_->[0] : $_ }
64 0           @{ $self->{modules} }
  0            
65             );
66             }
67              
68             sub recommend {
69 0     0 1   my ( $self ) = @_;
70 0 0         my @missing = $self->check()
71             or return;
72 0 0         my $tplt = @missing > 1 ?
73             $self->RECOMMEND_TEMPLATE_MULTI() :
74             $self->RECOMMEND_TEMPLATE_SINGLE();
75             return sprintf( $tplt, join ', ', _module_stringify( @missing ) ) .
76 0           $self->{message};
77             }
78              
79             sub _module_stringify {
80 0     0     my @arg = @_;
81 0           my @rslt;
82 0           foreach my $m ( @arg ) {
83 0 0         push @rslt, ARRAY_REF eq ref $m ? "@{ $m }" : $m;
  0            
84             }
85 0           return @rslt;
86             }
87              
88             1;
89              
90             __END__