File Coverage

blib/lib/experimental.pm
Criterion Covered Total %
statement 27 49 55.1
branch 10 32 31.2
condition 0 2 0.0
subroutine 7 9 77.7
pod n/a
total 44 92 47.8


line stmt bran cond sub pod time code
1             package experimental;
2             $experimental::VERSION = '0.036';
3 1     1   414068 use strict;
  1         2  
  1         46  
4 1     1   6 use warnings;
  1         2  
  1         112  
5 1     1   8 use version ();
  1         3  
  1         36  
6              
7 1     1   3 BEGIN { eval { require feature } };
  1         30  
8 1     1   4 use Carp qw/croak carp/;
  1         2  
  1         1482  
9              
10             my %warnings = map { $_ => 1 } grep { /^experimental::/ } keys %warnings::Offsets;
11             my %removed_warnings = map { $_ => 1 } grep { /^experimental::/ } keys %warnings::NoOp;
12             my %features = map { $_ => 1 } $] > 5.015006 ? keys %feature::feature : do {
13             my @features;
14             if ($] >= 5.010) {
15             push @features, qw/switch say state/;
16             push @features, 'unicode_strings' if $] > 5.011002;
17             }
18             @features;
19             };
20              
21             my %min_version = (
22             args_array_with_signatures => '5.20.0',
23             array_base => '5',
24             autoderef => '5.14.0',
25             bitwise => '5.22.0',
26             builtin => '5.35.7',
27             class => '5.37.9',
28             const_attr => '5.22.0',
29             current_sub => '5.16.0',
30             declared_refs => '5.26.0',
31             defer => '5.35.4',
32             evalbytes => '5.16.0',
33             extra_paired_delimiters => '5.35.9',
34             fc => '5.16.0',
35             for_list => '5.35.5',
36             isa => '5.31.7',
37             keyword_all => '5.41.7',
38             keyword_any => '5.41.7',
39             lexical_topic => '5.10.0',
40             lexical_subs => '5.18.0',
41             postderef => '5.20.0',
42             postderef_qq => '5.20.0',
43             refaliasing => '5.22.0',
44             regex_sets => '5.18.0',
45             say => '5.10.0',
46             smartmatch => '5.10.0',
47             signatures => '5.20.0',
48             state => '5.10.0',
49             switch => '5.10.0',
50             try => '5.34.0',
51             unicode_eval => '5.16.0',
52             unicode_strings => '5.12.0',
53             win32_perlio => '5.8.0',
54             );
55             my %removed_in_version = (
56             array_base => '5.30.0',
57             autoderef => '5.24.0',
58             lexical_topic => '5.24.0',
59             win32_perlio => '5.36.0',
60             );
61              
62             $_ = version->new($_) for values %min_version;
63             $_ = version->new($_) for values %removed_in_version;
64              
65             my %additional = (
66             postderef => ['postderef_qq'],
67             switch => ['smartmatch'],
68             declared_refs => ['refaliasing'],
69             );
70              
71             sub _enable {
72 4     4   9 my $pragma = shift;
73 4 100 0     23 if ($warnings{"experimental::$pragma"}) {
    100          
    50          
    0          
    0          
    0          
74 2         56 warnings->unimport("experimental::$pragma");
75 2 50       152 feature->import($pragma) if exists $features{$pragma};
76 2 100       14 _enable(@{ $additional{$pragma} }) if $additional{$pragma};
  1         7  
77             }
78             elsif ($features{$pragma}) {
79 1         146 feature->import($pragma);
80 1 50       7 _enable(@{ $additional{$pragma} }) if $additional{$pragma};
  0         0  
81             }
82             elsif ($removed_warnings{"experimental::$pragma"}) {
83 1 50       5 _enable(@{ $additional{$pragma} }) if $additional{$pragma};
  0         0  
84             }
85             elsif (not exists $min_version{$pragma}) {
86 0         0 croak "Can't enable unknown feature $pragma";
87             }
88             elsif ($] < $min_version{$pragma}) {
89 0         0 my $stable = $min_version{$pragma}->stringify;
90 0         0 $stable =~ s/^ 5\. ([0-9]?[13579]) \. \d+ $/"5." . ($1 + 1) . ".0"/xe;
  0         0  
91 0         0 croak "Need perl $stable or later for feature $pragma";
92             }
93             elsif ($] >= ($removed_in_version{$pragma} || 7)) {
94 0         0 croak "Experimental feature $pragma has been removed from perl in version $removed_in_version{$pragma}";
95             }
96             }
97              
98             sub import {
99 3     3   4254 my ($self, @pragmas) = @_;
100              
101 3         8 for my $pragma (@pragmas) {
102 3         11 _enable($pragma);
103             }
104 3         276 return;
105             }
106              
107             sub _disable {
108 0     0     my $pragma = shift;
109 0 0         if ($warnings{"experimental::$pragma"}) {
    0          
    0          
110 0           warnings->import("experimental::$pragma");
111 0 0         feature->unimport($pragma) if exists $features{$pragma};
112 0 0         _disable(@{ $additional{$pragma} }) if $additional{$pragma};
  0            
113             }
114             elsif ($features{$pragma}) {
115 0           feature->unimport($pragma);
116 0 0         _disable(@{ $additional{$pragma} }) if $additional{$pragma};
  0            
117             }
118             elsif (not exists $min_version{$pragma}) {
119 0           carp "Can't disable unknown feature $pragma, ignoring";
120             }
121             }
122              
123             sub unimport {
124 0     0     my ($self, @pragmas) = @_;
125              
126 0           for my $pragma (@pragmas) {
127 0           _disable($pragma);
128             }
129 0           return;
130             }
131              
132             1;
133              
134             #ABSTRACT: Experimental features made easy
135              
136             __END__