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