Commit | Line | Data |
---|---|---|
de84ff2b | 1 | package experimental; |
4177cbce | 2 | $experimental::VERSION = '0.011'; |
de84ff2b RS |
3 | use strict; |
4 | use warnings; | |
edd0583e | 5 | use version (); |
de84ff2b RS |
6 | |
7 | use feature (); | |
8 | use Carp qw/croak carp/; | |
9 | ||
10 | my %warnings = map { $_ => 1 } grep { /^experimental::/ } keys %warnings::Offsets; | |
f8c3bb9c CBW |
11 | my %features = map { $_ => 1 } $] > 5.015006 ? keys %feature::feature : do { |
12 | my @features; | |
13 | if ($] >= 5.010) { | |
14 | push @features, qw/switch say state/; | |
15 | push @features, 'unicode_strings' if $] > 5.011002; | |
16 | } | |
17 | @features; | |
18 | }; | |
de84ff2b RS |
19 | |
20 | my %min_version = ( | |
f8c3bb9c CBW |
21 | array_base => '5', |
22 | autoderef => '5.14.0', | |
23 | current_sub => '5.16.0', | |
24 | evalbytes => '5.16.0', | |
25 | fc => '5.16.0', | |
26 | lexical_topic => '5.10.0', | |
27 | lexical_subs => '5.18.0', | |
28 | postderef => '5.20.0', | |
29 | postderef_qq => '5.20.0', | |
30 | regex_sets => '5.18.0', | |
31 | say => '5.10.0', | |
32 | smartmatch => '5.10.0', | |
33 | signatures => '5.20.0', | |
34 | state => '5.10.0', | |
35 | switch => '5.10.0', | |
36 | unicode_eval => '5.16.0', | |
37 | unicode_strings => '5.12.0', | |
de84ff2b | 38 | ); |
f8c3bb9c | 39 | $_ = version->new($_) for values %min_version; |
de84ff2b RS |
40 | |
41 | my %additional = ( | |
42 | postderef => ['postderef_qq'], | |
43 | switch => ['smartmatch'], | |
44 | ); | |
45 | ||
46 | sub _enable { | |
47 | my $pragma = shift; | |
48 | if ($warnings{"experimental::$pragma"}) { | |
49 | warnings->unimport("experimental::$pragma"); | |
50 | feature->import($pragma) if exists $features{$pragma}; | |
51 | _enable(@{ $additional{$pragma} }) if $additional{$pragma}; | |
52 | } | |
53 | elsif ($features{$pragma}) { | |
54 | feature->import($pragma); | |
55 | _enable(@{ $additional{$pragma} }) if $additional{$pragma}; | |
56 | } | |
57 | elsif (not exists $min_version{$pragma}) { | |
58 | croak "Can't enable unknown feature $pragma"; | |
59 | } | |
60 | elsif ($min_version{$pragma} > $]) { | |
edd0583e | 61 | croak "Need perl $min_version{$pragma} or later for feature $pragma"; |
de84ff2b RS |
62 | } |
63 | } | |
64 | ||
65 | sub import { | |
66 | my ($self, @pragmas) = @_; | |
67 | ||
68 | for my $pragma (@pragmas) { | |
69 | _enable($pragma); | |
70 | } | |
71 | return; | |
72 | } | |
73 | ||
74 | sub _disable { | |
75 | my $pragma = shift; | |
76 | if ($warnings{"experimental::$pragma"}) { | |
77 | warnings->import("experimental::$pragma"); | |
78 | feature->unimport($pragma) if exists $features{$pragma}; | |
79 | _disable(@{ $additional{$pragma} }) if $additional{$pragma}; | |
80 | } | |
81 | elsif ($features{$pragma}) { | |
82 | feature->unimport($pragma); | |
83 | _disable(@{ $additional{$pragma} }) if $additional{$pragma}; | |
84 | } | |
85 | elsif (not exists $min_version{$pragma}) { | |
86 | carp "Can't disable unknown feature $pragma, ignoring"; | |
87 | } | |
88 | } | |
89 | ||
90 | sub unimport { | |
91 | my ($self, @pragmas) = @_; | |
92 | ||
93 | for my $pragma (@pragmas) { | |
94 | _disable($pragma); | |
95 | } | |
96 | return; | |
97 | } | |
98 | ||
99 | 1; | |
100 | ||
101 | #ABSTRACT: Experimental features made easy | |
102 | ||
103 | __END__ | |
104 | ||
105 | =pod | |
106 | ||
107 | =encoding UTF-8 | |
108 | ||
109 | =head1 NAME | |
110 | ||
111 | experimental - Experimental features made easy | |
112 | ||
113 | =head1 VERSION | |
114 | ||
4177cbce | 115 | version 0.011 |
de84ff2b RS |
116 | |
117 | =head1 SYNOPSIS | |
118 | ||
119 | use experimental 'lexical_subs', 'smartmatch'; | |
120 | my sub foo { $_[0] ~~ 1 } | |
121 | ||
122 | =head1 DESCRIPTION | |
123 | ||
124 | This pragma provides an easy and convenient way to enable or disable | |
125 | experimental features. | |
126 | ||
127 | Every version of perl has some number of features present but considered | |
128 | "experimental." For much of the life of Perl 5, this was only a designation | |
129 | found in the documentation. Starting in Perl v5.10.0, and more aggressively in | |
130 | v5.18.0, experimental features were placed behind pragmata used to enable the | |
131 | feature and disable associated warnings. | |
132 | ||
133 | The C<experimental> pragma exists to combine the required incantations into a | |
134 | single interface stable across releases of perl. For every experimental | |
135 | feature, this should enable the feature and silence warnings for the enclosing | |
136 | lexical scope: | |
137 | ||
138 | use experimental 'feature-name'; | |
139 | ||
140 | To disable the feature and, if applicable, re-enable any warnings, use: | |
141 | ||
142 | no experimental 'feature-name'; | |
143 | ||
144 | The supported features, documented further below, are: | |
145 | ||
146 | array_base - allow the use of $[ to change the starting index of @array | |
147 | autoderef - allow push, each, keys, and other built-ins on references | |
148 | lexical_topic - allow the use of lexical $_ via "my $_" | |
149 | postderef - allow the use of postfix dereferencing expressions, including | |
150 | in interpolating strings | |
151 | regex_sets - allow extended bracketed character classes in regexps | |
152 | signatures - allow subroutine signatures (for named arguments) | |
edd0583e CBW |
153 | smartmatch - allow the use of ~~ |
154 | switch - allow the use of ~~, given, and when | |
de84ff2b | 155 | |
4177cbce CBW |
156 | =head2 Ordering matters |
157 | ||
158 | Using this pragma to 'enable an experimental feature' is another way of saying | |
159 | that this pragma will disable the warnings which would result from using that | |
160 | feature. Therefore, the order in which pragmas are applied is important. In | |
161 | particular, you probably want to enable experimental features I<after> you | |
162 | enable warnings: | |
163 | ||
164 | use warnings; | |
165 | use experimental 'smartmatch'; | |
166 | ||
167 | You also need to take care with modules that enable warnings for you. A common | |
168 | example being Moose. In this example, warnings for the 'smartmatch' feature are | |
169 | first turned on by the warnings pragma, off by the experimental pragma and back | |
170 | on again by the Moose module (fix is to switch the last two lines): | |
171 | ||
172 | use warnings; | |
173 | use experimental 'smartmatch'; | |
174 | use Moose; | |
175 | ||
de84ff2b RS |
176 | =head2 Disclaimer |
177 | ||
178 | Because of the nature of the features it enables, forward compatibility can not | |
179 | be guaranteed in any way. | |
180 | ||
181 | =head1 AUTHOR | |
182 | ||
183 | Leon Timmermans <leont@cpan.org> | |
184 | ||
185 | =head1 COPYRIGHT AND LICENSE | |
186 | ||
187 | This software is copyright (c) 2013 by Leon Timmermans. | |
188 | ||
189 | This is free software; you can redistribute it and/or modify it under | |
190 | the same terms as the Perl 5 programming language system itself. | |
191 | ||
192 | =cut |