File Coverage

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


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