File Coverage

blib/lib/ex/implements.pm
Criterion Covered Total %
statement 34 36 94.4
branch 10 16 62.5
condition 1 3 33.3
subroutine 5 5 100.0
pod n/a
total 50 60 83.3


line stmt bran cond sub pod time code
1             package ex::implements;
2              
3 4     4   2387 use strict;
  4         8  
  4         145  
4 4     4   21 no strict 'refs';
  4         6  
  4         311  
5              
6             require 5.6.0;
7              
8             my %IMPLEMENTS = ();
9              
10              
11             sub import {
12 3     3   65 my $class = shift;
13 3         10 my $pkg = caller(0);
14              
15 3         11 foreach my $interface (@_) {
16 3 50       46 next if $pkg->isa($interface);
17 4     4   19 no strict 'refs';
  4         7  
  4         6415  
18 3         7 push @{"$pkg\::ISA"}, $interface;
  3         43  
19 3 50       23 unless (exists $::{"$interface\::"}{"VERSION"}) {
20 3         215 eval "require $interface";
21             # Only ignore "Can't locate" errors from our eval require.
22             # Other fatals must be reported
23 3 50 33     64 die if $@ && $@ !~ /^Can\'t locate .*? at \(eval /;
24 3 50       13 unless (%{"$interface\::"}) {
  3         21  
25 0         0 require Carp;
26 0         0 Carp::croak("Interface package \"$interface\" is empty.\n",
27             "\t(Perhaps you need to 'use' the module ",
28             "which defines that package first.)");
29             }
30 3 50       17 $ {"$interface\::VERSION"} = "-1, set by implements.pm"
  3         25  
31             unless exists $::{"$interface\::"}{"VERSION"};
32             }
33 3         2066 $IMPLEMENTS{$pkg}{$interface} = undef;
34             }
35             }
36              
37             CHECK {
38 3     3   8 my $error_count = 0;
39 3         22 foreach my $pkg (keys %IMPLEMENTS) {
40 3         6 foreach my $interface (keys %{$IMPLEMENTS{$pkg}}) {
  3         10  
41 9         90 my @unimplemented =
42 3         17 grep {! $pkg->can($_)}
43 3         7 keys %{"$interface\::__METHOD"};
44 3 100       20 if (@unimplemented) {
45 1 50       56 warn("$pkg\: Method",
46             (@unimplemented == 1 ? " '$unimplemented[0]'\n\tis " :
47             ("s '",
48             join("', '", @unimplemented[0 .. $#unimplemented-1]),
49             "' and '$unimplemented[-1]'\n\tare ")),
50             "missing for interface $interface\n");
51 1         5 $error_count++;
52             }
53             }
54             }
55 3 100       4728 exit(1) if $error_count;
56             }
57              
58             1;