File Coverage

blib/lib/UNIVERSAL/DOES.pm
Criterion Covered Total %
statement 22 37 59.4
branch 11 18 61.1
condition 6 6 100.0
subroutine 4 5 80.0
pod 2 2 100.0
total 45 68 66.1


line stmt bran cond sub pod time code
1             package UNIVERSAL::DOES;
2              
3 3     3   79066 use 5.005_03;
  3         14  
  3         184  
4              
5             $VERSION = '0.005';
6              
7 3     3   17 use Exporter;
  3         5  
  3         208  
8             @ISA = qw(Exporter);
9             @EXPORT_OK = qw(does);
10              
11 3     3   26 use strict;
  3         10  
  3         1556  
12              
13             *UNIVERSAL::DOES = \&DOES
14             unless defined &UNIVERSAL::DOES;
15              
16             # Take compatibility rather than performance.
17             sub DOES :method {
18 0     0 1 0 my($invocant, $role) = @_;
19              
20 0 0       0 if(@_ != 2){
21 0         0 require Carp;
22 0         0 Carp::croak('Usage: invocant->DOES(kind)');
23             }
24              
25 0         0 my $e = do{
26 0         0 local $@;
27 0 0       0 eval{ $invocant->isa($role) } and return 1;
  0         0  
28 0         0 $@;
29             };
30              
31 0 0       0 if($e){
32 0         0 $e =~ s/\b isa \b/DOES/xmsg;
33 0         0 die $e;
34             }
35              
36 0         0 return 0;
37             }
38              
39             my %operator_of = (
40             SCALAR => '${}',
41             ARRAY => '@{}',
42             HASH => '%{}',
43             CODE => '&{}',
44             GLOB => '*{}',
45             );
46              
47             sub does {
48 38     38 1 813 my($thing, $role) = @_;
49              
50 38 50       91 if(@_ != 2){
51 0         0 require Carp;
52 0         0 Carp::croak('Usage: does(thing, role)');
53             }
54              
55 38 100 100     243 return 0 unless $thing && $role;
56              
57 36         42 my $e = do{
58 36         44 local $@;
59 36 100       55 eval{ $thing->DOES($role) } and return 1;
  36         259  
60 14         44 $@;
61             };
62              
63 14 100       57 if($e){ # $thing is not an invocant
    100          
64 6         30 return ref($thing) eq $role; # ARRAY, HASH, etc.
65             }
66             elsif(ref($thing)){ # $thins is an object
67 7 100       23 my $operator = $operator_of{$role} or return 0;
68              
69 6   100     83 return $thing->can('()') # overloaded?
70             && $thing->can('(' . $operator); # with the dereferencing operator?
71             }
72              
73 1         5 return 0;
74             }
75              
76             1;
77             __END__