File Coverage

blib/lib/UNIVERSAL/isa.pm
Criterion Covered Total %
statement 63 63 100.0
branch 30 34 88.2
condition 3 6 50.0
subroutine 17 17 100.0
pod 1 1 100.0
total 114 121 94.2


line stmt bran cond sub pod time code
1             package UNIVERSAL::isa;
2             # git description: 1.20140824-2-g1cfb04c
3             $UNIVERSAL::isa::VERSION = '1.20140927';
4             # ABSTRACT: Attempt to recover from people calling UNIVERSAL::isa as a function
5              
6 3     3   41395 use strict;
  3         4  
  3         82  
7 3     3   11 use warnings;
  3         3  
  3         52  
8 3     3   22 use 5.6.2;
  3         6  
  3         80  
9              
10 3     3   1446 use UNIVERSAL ();
  3         31  
  3         63  
11 3     3   10 use Scalar::Util 'blessed';
  3         3  
  3         235  
12 3     3   13 use warnings::register;
  3         4  
  3         345  
13              
14             my ( $orig, $verbose_warning );
15              
16 3     3   71 BEGIN { $orig = \&UNIVERSAL::isa }
17              
18             sub import
19             {
20 5     5   830 my $class = shift;
21 3     3   15 no strict 'refs';
  3         3  
  3         224  
22              
23 5         11 for my $arg (@_)
24             {
25 5 100       17 *{ caller() . '::isa' } = \&UNIVERSAL::isa if $arg eq 'isa';
  3         14  
26 5 100       455 $verbose_warning = 1 if $arg eq 'verbose';
27             }
28             }
29              
30             our $_recursing;
31              
32 3     3   13 no warnings 'redefine';
  3         3  
  3         211  
33             sub UNIVERSAL::isa
34             {
35 615 100   615 1 193282 goto &$orig if $_recursing;
36 611         725 my $type = _invocant_type(@_);
37 611         869 $type->(@_);
38             }
39 3     3   12 use warnings;
  3         3  
  3         913  
40              
41             sub _invocant_type
42             {
43 611     611   451 my $invocant = shift;
44 611 100       826 return \&_nonsense unless defined($invocant);
45 607 100       1474 return \&_object_or_class if blessed($invocant);
46 20 100       56 return \&_reference if ref($invocant);
47 9 100       17 return \&_nonsense unless $invocant;
48 8         18 return \&_object_or_class;
49             }
50              
51             sub _nonsense
52             {
53 5 100   5   11 _report_warning('on invalid invocant') if $verbose_warning;
54 5         19 return;
55             }
56              
57             sub _object_or_class
58             {
59 595     595   425 local $@;
60 595         440 local $_recursing = 1;
61              
62 595 50       566 if ( my $override = eval { $_[0]->can('isa') } )
  595         1448  
63             {
64 595 100       1022 unless ( $override == \&UNIVERSAL::isa )
65             {
66 16         27 _report_warning();
67 16         437 my $obj = shift;
68 16         35 return $obj->$override(@_);
69             }
70             }
71              
72 579 100       782 _report_warning() if $verbose_warning;
73 579         14876 goto &$orig;
74             }
75              
76             sub _reference
77             {
78 11 100   11   21 _report_warning('Did you mean to use Scalar::Util::reftype() instead?')
79             if $verbose_warning;
80 11         203 goto &$orig;
81             }
82              
83             sub _report_warning
84             {
85 26     26   23 my $extra = shift;
86 26 100       48 $extra = $extra ? " ($extra)" : '';
87              
88 26 100       1538 if ( warnings::enabled() )
89             {
90             # check calling sub
91 24 50 50     115 return if (( caller(3) )[3] || '') =~ /::isa$/;
92             # check calling package - exempt Test::Builder??
93 24 50 50     84 return if (( caller(3) )[0] || '') =~ /^Test::Builder/;
94 24 50 50     119 return if (( caller(2) )[0] || '') =~ /^Test::Stream/;
95              
96 24         3133 warnings::warn(
97             "Called UNIVERSAL::isa() as a function, not a method$extra" );
98             }
99             }
100              
101             __PACKAGE__;
102              
103             __END__