File Coverage

blib/lib/builtins/compat.pm
Criterion Covered Total %
statement 50 52 98.0
branch 11 12 91.6
condition 12 14 85.7
subroutine 16 16 100.0
pod 0 2 0.0
total 89 96 93.7


line stmt bran cond sub pod time code
1 5     5   114859 use 5.008001;
  5         37  
2 5     5   23 use strict;
  5         21  
  5         93  
3 5     5   19 use warnings;
  5         8  
  5         542  
4              
5             package builtins::compat;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.002';
9              
10             sub _true () {
11             !!1;
12             }
13              
14             sub _false () {
15             !!0;
16             }
17              
18             BEGIN {
19             # uncoverable statement
20 5 50   5   614 *LEGACY_PERL = ( $] lt '5.036' ) ? \&_true : \&_false;
21             };
22              
23             sub import {
24 4     4   28 goto \&import_compat if LEGACY_PERL;
25              
26             # uncoverable statement
27 0         0 'warnings'->unimport('experimental::builtin');
28              
29             # uncoverable statement
30 0         0 'builtin'->import( qw<
31             true false is_bool
32             weaken unweaken is_weak
33             blessed refaddr reftype
34             created_as_string created_as_number
35             ceil floor
36             trim
37             indexed
38             > );
39             }
40              
41             sub import_compat {
42 4     4 0 8 my $class = shift;
43              
44 4         8 my $caller = caller;
45 4         7 my $subs = $class->get_subs;
46              
47 4         12 while ( my ( $name, $code ) = each %$subs ) {
48 5     5   30 no strict 'refs';
  5         9  
  5         1312  
49 60         70 *{"$caller\::$name"} = $code;
  60         215  
50             }
51              
52 4         1629 require namespace::clean;
53 4         52805 'namespace::clean'->import(
54             -cleanee => $caller,
55             keys %$subs,
56             );
57             }
58              
59             {
60             my $subs;
61             sub get_subs {
62 9     9 0 36 require Scalar::Util;
63 9         145 'Scalar::Util'->VERSION( '1.36' );
64              
65 9   100     119 $subs ||= {
66             true => \&_true,
67             false => \&_false,
68             is_bool => \&_is_bool,
69             weaken => \&Scalar::Util::weaken,
70             unweaken => \&Scalar::Util::unweaken,
71             is_weak => \&Scalar::Util::isweak,
72             blessed => \&Scalar::Util::blessed,
73             refaddr => \&Scalar::Util::refaddr,
74             reftype => \&Scalar::Util::reftype,
75             weaken => \&Scalar::Util::weaken,
76             created_as_string => \&_created_as_string,
77             created_as_number => \&_created_as_number,
78             ceil => \&_ceil, # POSIX::ceil has wrong prototype
79             floor => \&_floor, # POSIX::floor has wrong prototype
80             trim => \&_trim,
81             indexed => \&_indexed,
82             };
83             }
84             }
85              
86             if ( LEGACY_PERL ) {
87             my $subs = __PACKAGE__->get_subs;
88             while ( my ( $name, $code ) = each %$subs ) {
89 5     5   29 no strict 'refs';
  5         9  
  5         2269  
90             *{"builtin::$name"} = $code
91             unless exists &{"builtin::$name"};
92             }
93             }
94              
95             sub _is_bool ($) {
96 39     39   1616 my $value = shift;
97              
98 39 100       70 return _false unless defined $value;
99 38 100       82 return _false if ref $value;
100 34 100       138 return _false unless Scalar::Util::isdual( $value );
101             return !! (
102 12   33     121 ( "$value" eq "1" or "$value" eq "" )
103             and ( $value+0 == 1 or $value+0 == 0 )
104             );
105             }
106              
107             sub _created_as_number ($) {
108 42     42   228 require B;
109              
110 42         62 my $value = shift;
111              
112 42         114 my $b_obj = B::svref_2object(\$value);
113 42         107 my $flags = $b_obj->FLAGS;
114 42 100 100     206 return _true if $flags & ( B::SVp_IOK() | B::SVp_NOK() ) and !( $flags & B::SVp_POK() );
115 26         107 return _false;
116             }
117              
118             sub _created_as_string ($) {
119 25     25   43 my $value = shift;
120              
121 25 100 100     115 defined($value)
      100        
122             && !ref($value)
123             && !_is_bool($value)
124             && !_created_as_number($value);
125             }
126              
127             sub _indexed {
128 2     2   4 my $ix = 0;
129 2         6 return map { $ix++, $_ } @_;
  6         21  
130             }
131              
132             sub _trim ($) {
133 2     2   6 my $value = shift;
134              
135 2         14 $value =~ s{^\s+|\s+$}{}g;
136 2         10 return $value;
137             }
138              
139             sub _ceil ($) {
140 2     2   13 require POSIX;
141 2         18 return POSIX::ceil( $_[0] );
142             }
143              
144             sub _floor ($) {
145 2     2   875 require POSIX;
146 2         10533 return POSIX::floor( $_[0] );
147             }
148              
149             1;
150              
151             __END__