File Coverage

blib/lib/UNIVERSAL/isa.pm
Criterion Covered Total %
statement 60 60 100.0
branch 31 34 91.1
condition 5 6 83.3
subroutine 17 17 100.0
pod 2 2 100.0
total 115 119 96.6


line stmt bran cond sub pod time code
1 3     3   145627 use strict;
  3         34  
  3         80  
2 3     3   15 use warnings;
  3         6  
  3         147  
3             package UNIVERSAL::isa; # git description: 1.20150614-11-gdfa589a
4             # ABSTRACT: Attempt to recover from people calling UNIVERSAL::isa as a function
5              
6             our $VERSION = '1.20171012';
7              
8 3     3   71 use 5.006002;
  3         10  
9              
10 3     3   15 use Scalar::Util ();
  3         7  
  3         63  
11 3     3   18 use warnings::register; # creates a warnings category for this module
  3         5  
  3         368  
12              
13             my ( $orig, $verbose_warning );
14              
15 3     3   116 BEGIN { $orig = \&UNIVERSAL::isa }
16              
17 632     632 1 19720 sub original_isa { goto $orig }
18              
19             sub import
20             {
21 5     5   1038 my $class = shift;
22 3     3   14 no strict 'refs';
  3         4  
  3         242  
23              
24 5         16 for my $arg (@_)
25             {
26 5 100       22 *{ caller() . '::isa' } = \&UNIVERSAL::isa if $arg eq 'isa';
  3         18  
27 5 100       516 $verbose_warning = 1 if $arg eq 'verbose';
28             }
29             }
30              
31             our $_recursing;
32              
33 3     3   15 no warnings 'redefine';
  3         3  
  3         203  
34             sub UNIVERSAL::isa
35             {
36 653 100   653 1 246128 goto &original_isa if $_recursing;
37 649         1101 my $type = _invocant_type(@_);
38 649         1187 $type->(@_);
39             }
40 3     3   16 use warnings;
  3         4  
  3         918  
41              
42             sub _invocant_type
43             {
44 649     649   863 my $invocant = shift;
45 649 100       1127 return \&_nonsense unless defined($invocant);
46 645 100       2060 return \&_object_or_class if Scalar::Util::blessed($invocant);
47 23 100       70 return \&_reference if ref($invocant);
48 12 100       39 return \&_nonsense unless $invocant;
49 11         26 return \&_object_or_class;
50             }
51              
52             sub _nonsense
53             {
54 5 100   5   16 _report_warning('on invalid invocant') if $verbose_warning;
55 5         27 return;
56             }
57              
58             sub _object_or_class
59             {
60 633     633   854 local $@;
61 633         852 local $_recursing = 1;
62              
63 633 50       984 if ( my $override = eval { $_[0]->can('isa') } )
  633         1931  
64             {
65 633 100       1514 unless ( $override == \&UNIVERSAL::isa )
66             {
67 16         38 _report_warning();
68 16         536 my $obj = shift;
69 16         41 return $obj->$override(@_);
70             }
71             }
72              
73 617 100       1189 _report_warning() if $verbose_warning;
74 617         1544 goto &original_isa;
75             }
76              
77             sub _reference
78             {
79 11 100   11   25 _report_warning('Did you mean to use Scalar::Util::reftype() instead?')
80             if $verbose_warning;
81 11         183 goto &original_isa;
82             }
83              
84             sub _report_warning
85             {
86 28     28   34 my $extra = shift;
87 28 100       65 $extra = $extra ? " ($extra)" : '';
88              
89 28 100       1476 if ( warnings::enabled() )
90             {
91             # check calling sub
92 25 50 100     153 return if (( caller(3) )[3] || '') =~ /::isa$/;
93             # check calling package - exempt Test::Builder??
94 25 100 100     86 return if (( caller(3) )[0] || '') =~ /^Test::Builder/;
95 24 50 50     105 return if (( caller(2) )[0] || '') =~ /^Test::Stream/;
96              
97 24         2562 warnings::warn(
98             "Called UNIVERSAL::isa() as a function, not a method$extra" );
99             }
100             }
101              
102             __PACKAGE__;
103              
104             __END__