File Coverage

blib/lib/match/simple.pm
Criterion Covered Total %
statement 21 21 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 29 29 100.0


line stmt bran cond sub pod time code
1             package match::simple;
2              
3 3     3   69772 use 5.006001;
  3         20  
4 3     3   15 use strict;
  3         4  
  3         59  
5 3     3   14 use warnings;
  3         6  
  3         80  
6              
7 3     3   895 use Exporter::Tiny;
  3         6579  
  3         18  
8 3     3   363 use List::Util 1.33 qw( any );
  3         65  
  3         333  
9 3     3   20 use Scalar::Util qw( blessed );
  3         6  
  3         177  
10              
11             BEGIN {
12 3     3   10 $match::simple::AUTHORITY = 'cpan:TOBYINK';
13 3         747 $match::simple::VERSION = '0.012';
14             }
15              
16             our @ISA = qw( Exporter::Tiny );
17             our @EXPORT = qw( M );
18             our @EXPORT_OK = qw( match );
19              
20             my $xs;
21             unless (($ENV{MATCH_SIMPLE_IMPLEMENTATION}||'') =~ /pp/i) {
22             eval {
23             require match::simple::XS;
24             match::simple::XS->VERSION( 0.002 ); # minimum
25            
26             # Unless we're a development version...
27             # Avoid using an unstable version of ::XS
28             unless (match::simple->VERSION =~ /_/) {
29             die if match::simple::XS->VERSION =~ /_/;
30             }
31            
32             $xs = match::simple::XS->can('match');
33             };
34             }
35              
36             eval($xs ? <<'XS' : <<'PP');
37              
38             sub IMPLEMENTATION () { "XS" }
39              
40             *match = *match::simple::XS::match;
41              
42             XS
43              
44             sub IMPLEMENTATION () { "PP" }
45              
46             sub match {
47             no warnings qw( uninitialized numeric );
48            
49             my ( $a, $b ) = @_;
50             my $method;
51            
52             return !defined $a if !defined($b);
53             return $a eq $b if !ref($b);
54             return $a =~ $b if ref($b) eq q(Regexp);
55             return do { local $_ = $a; !!$b->($a) } if ref($b) eq q(CODE);
56             return any { match( $a, $_ ) } @$b if ref($b) eq q(ARRAY);
57             return !!$b->$method( $a, 1 ) if blessed($b) && ( $method = _overloaded_smartmatch( $b ) );
58            
59             require Carp;
60             Carp::croak( "match::simple cannot match anything against: $b" );
61             }
62              
63             unless ( eval 'require re; 1' and exists &re::is_regexp ) {
64             require B;
65             *re::is_regexp = sub {
66             eval { B::svref_2object( $_[0] )->MAGIC->TYPE eq 'r' };
67             };
68             }
69              
70             sub _overloaded_smartmatch {
71             my ( $obj ) = @_;
72             return if re::is_regexp( $obj );
73            
74             if ( $obj->isa( 'Type::Tiny' ) ) {
75             return $obj->can( 'check' );
76             }
77            
78             if ( my $match = $obj->can( 'MATCH' ) ) {
79             return $match;
80             }
81            
82             if ( $] lt '5.010' ) { require MRO::Compat; }
83             else { require mro; }
84            
85             my @mro = @{ mro::get_linear_isa( ref $obj ) };
86             for my $class ( @mro ) {
87             my $name = "$class\::(~~";
88             my $overload = do {
89             no strict 'refs';
90             exists( &$name ) ? \&$name : undef;
91             };
92             return $overload if $overload;
93             }
94            
95             return;
96             }
97              
98             PP
99              
100             sub _generate_M {
101 2     2   1082 require Sub::Infix;
102 2         4278 &Sub::Infix::infix( \&match );
103             }
104              
105             1;
106              
107             __END__