File Coverage

blib/lib/UNIVERSAL/isa.pm
Criterion Covered Total %
statement 60 60 100.0
branch 30 34 88.2
condition 3 6 50.0
subroutine 16 16 100.0
pod 1 1 100.0
total 110 117 94.0


line stmt bran cond sub pod time code
1 3     3   55683 use strict;
  3         7  
  3         165  
2 3     3   19 use warnings;
  3         4  
  3         180  
3             package UNIVERSAL::isa; # git description: 1.20140927-9-g397ee12
4             # ABSTRACT: Attempt to recover from people calling UNIVERSAL::isa as a function
5              
6             our $VERSION = '1.20150614';
7              
8 3     3   72 use 5.006002;
  3         9  
  3         108  
9              
10 3     3   16 use Scalar::Util ();
  3         11  
  3         66  
11 3     3   23 use warnings::register; # creates a warnings category for this module
  3         4  
  3         493  
12              
13             my ( $orig, $verbose_warning );
14              
15 3     3   111 BEGIN { $orig = \&UNIVERSAL::isa }
16              
17             sub import
18             {
19 5     5   977 my $class = shift;
20 3     3   23 no strict 'refs';
  3         4  
  3         321  
21              
22 5         13 for my $arg (@_)
23             {
24 5 100       21 *{ caller() . '::isa' } = \&UNIVERSAL::isa if $arg eq 'isa';
  3         17  
25 5 100       501 $verbose_warning = 1 if $arg eq 'verbose';
26             }
27             }
28              
29             our $_recursing;
30              
31 3     3   16 no warnings 'redefine';
  3         4  
  3         256  
32             sub UNIVERSAL::isa
33             {
34 615 100   615 1 245745 goto &$orig if $_recursing;
35 611         712 my $type = _invocant_type(@_);
36 611         900 $type->(@_);
37             }
38 3     3   19 use warnings;
  3         4  
  3         1111  
39              
40             sub _invocant_type
41             {
42 611     611   467 my $invocant = shift;
43 611 100       882 return \&_nonsense unless defined($invocant);
44 607 100       1617 return \&_object_or_class if Scalar::Util::blessed($invocant);
45 20 100       74 return \&_reference if ref($invocant);
46 9 100       31 return \&_nonsense unless $invocant;
47 8         26 return \&_object_or_class;
48             }
49              
50             sub _nonsense
51             {
52 5 100   5   17 _report_warning('on invalid invocant') if $verbose_warning;
53 5         75 return;
54             }
55              
56             sub _object_or_class
57             {
58 595     595   420 local $@;
59 595         479 local $_recursing = 1;
60              
61 595 50       582 if ( my $override = eval { $_[0]->can('isa') } )
  595         1537  
62             {
63 595 100       1118 unless ( $override == \&UNIVERSAL::isa )
64             {
65 16         35 _report_warning();
66 16         561 my $obj = shift;
67 16         45 return $obj->$override(@_);
68             }
69             }
70              
71 579 100       856 _report_warning() if $verbose_warning;
72 579         17331 goto &$orig;
73             }
74              
75             sub _reference
76             {
77 11 100   11   22 _report_warning('Did you mean to use Scalar::Util::reftype() instead?')
78             if $verbose_warning;
79 11         308 goto &$orig;
80             }
81              
82             sub _report_warning
83             {
84 26     26   27 my $extra = shift;
85 26 100       62 $extra = $extra ? " ($extra)" : '';
86              
87 26 100       1865 if ( warnings::enabled() )
88             {
89             # check calling sub
90 24 50 50     125 return if (( caller(3) )[3] || '') =~ /::isa$/;
91             # check calling package - exempt Test::Builder??
92 24 50 50     91 return if (( caller(3) )[0] || '') =~ /^Test::Builder/;
93 24 50 50     118 return if (( caller(2) )[0] || '') =~ /^Test::Stream/;
94              
95 24         3693 warnings::warn(
96             "Called UNIVERSAL::isa() as a function, not a method$extra" );
97             }
98             }
99              
100             __PACKAGE__;
101              
102             __END__