Update File::Copy tests to skip on OpenBSD, as it mounts too many filesystems nosuid.
[p5sagit/p5-mst-13.2.git] / lib / feature.pm
1 package feature;
2
3 our $VERSION = '1.13';
4
5 # (feature name) => (internal name, used in %^H)
6 my %feature = (
7     switch => 'feature_switch',
8     say    => "feature_say",
9     state  => "feature_state",
10 );
11
12 # NB. the latest bundle must be loaded by the -E switch (see toke.c)
13
14 my %feature_bundle = (
15     "5.10" => [qw(switch say state)],
16     "5.11" => [qw(switch say state)],
17 );
18
19 # special case
20 $feature_bundle{"5.9.5"} = $feature_bundle{"5.10"};
21
22 # TODO:
23 # - think about versioned features (use feature switch => 2)
24
25 =head1 NAME
26
27 feature - Perl pragma to enable new syntactic features
28
29 =head1 SYNOPSIS
30
31     use feature qw(switch say);
32     given ($foo) {
33         when (1)          { say "\$foo == 1" }
34         when ([2,3])      { say "\$foo == 2 || \$foo == 3" }
35         when (/^a[bc]d$/) { say "\$foo eq 'abd' || \$foo eq 'acd'" }
36         when ($_ > 100)   { say "\$foo > 100" }
37         default           { say "None of the above" }
38     }
39
40     use feature ':5.10'; # loads all features available in perl 5.10
41
42 =head1 DESCRIPTION
43
44 It is usually impossible to add new syntax to Perl without breaking
45 some existing programs. This pragma provides a way to minimize that
46 risk. New syntactic constructs can be enabled by C<use feature 'foo'>,
47 and will be parsed only when the appropriate feature pragma is in
48 scope.
49
50 =head2 Lexical effect
51
52 Like other pragmas (C<use strict>, for example), features have a lexical
53 effect. C<use feature qw(foo)> will only make the feature "foo" available
54 from that point to the end of the enclosing block.
55
56     {
57         use feature 'say';
58         say "say is available here";
59     }
60     print "But not here.\n";
61
62 =head2 C<no feature>
63
64 Features can also be turned off by using C<no feature "foo">. This too
65 has lexical effect.
66
67     use feature 'say';
68     say "say is available here";
69     {
70         no feature 'say';
71         print "But not here.\n";
72     }
73     say "Yet it is here.";
74
75 C<no feature> with no features specified will turn off all features.
76
77 =head2 The 'switch' feature
78
79 C<use feature 'switch'> tells the compiler to enable the Perl 6
80 given/when construct.
81
82 See L<perlsyn/"Switch statements"> for details.
83
84 =head2 The 'say' feature
85
86 C<use feature 'say'> tells the compiler to enable the Perl 6
87 C<say> function.
88
89 See L<perlfunc/say> for details.
90
91 =head2 the 'state' feature
92
93 C<use feature 'state'> tells the compiler to enable C<state>
94 variables.
95
96 See L<perlsub/"Persistent Private Variables"> for details.
97
98 =head1 FEATURE BUNDLES
99
100 It's possible to load a whole slew of features in one go, using
101 a I<feature bundle>. The name of a feature bundle is prefixed with
102 a colon, to distinguish it from an actual feature. At present, the
103 only feature bundle is C<use feature ":5.10"> which is equivalent
104 to C<use feature qw(switch say state)>.
105
106 Specifying sub-versions such as the C<0> in C<5.10.0> in feature bundles has
107 no effect: feature bundles are guaranteed to be the same for all sub-versions.
108
109 =head1 IMPLICIT LOADING
110
111 There are two ways to load the C<feature> pragma implicitly :
112
113 =over 4
114
115 =item *
116
117 By using the C<-E> switch on the command-line instead of C<-e>. It enables
118 all available features in the main compilation unit (that is, the one-liner.)
119
120 =item *
121
122 By requiring explicitly a minimal Perl version number for your program, with
123 the C<use VERSION> construct, and when the version is higher than or equal to
124 5.10.0. That is,
125
126     use 5.10.0;
127
128 will do an implicit
129
130     use feature ':5.10';
131
132 and so on. Note how the trailing sub-version is automatically stripped from the
133 version.
134
135 But to avoid portability warnings (see L<perlfunc/use>), you may prefer:
136
137     use 5.010;
138
139 with the same effect.
140
141 =back
142
143 =cut
144
145 sub import {
146     my $class = shift;
147     if (@_ == 0) {
148         croak("No features specified");
149     }
150     while (@_) {
151         my $name = shift(@_);
152         if (substr($name, 0, 1) eq ":") {
153             my $v = substr($name, 1);
154             if (!exists $feature_bundle{$v}) {
155                 $v =~ s/^([0-9]+)\.([0-9]+).[0-9]+$/$1.$2/;
156                 if (!exists $feature_bundle{$v}) {
157                     unknown_feature_bundle(substr($name, 1));
158                 }
159             }
160             unshift @_, @{$feature_bundle{$v}};
161             next;
162         }
163         if (!exists $feature{$name}) {
164             unknown_feature($name);
165         }
166         $^H{$feature{$name}} = 1;
167     }
168 }
169
170 sub unimport {
171     my $class = shift;
172
173     # A bare C<no feature> should disable *all* features
174     if (!@_) {
175         delete @^H{ values(%feature) };
176         return;
177     }
178
179     while (@_) {
180         my $name = shift;
181         if (substr($name, 0, 1) eq ":") {
182             my $v = substr($name, 1);
183             if (!exists $feature_bundle{$v}) {
184                 $v =~ s/^([0-9]+)\.([0-9]+).[0-9]+$/$1.$2/;
185                 if (!exists $feature_bundle{$v}) {
186                     unknown_feature_bundle(substr($name, 1));
187                 }
188             }
189             unshift @_, @{$feature_bundle{$v}};
190             next;
191         }
192         if (!exists($feature{$name})) {
193             unknown_feature($name);
194         }
195         else {
196             delete $^H{$feature{$name}};
197         }
198     }
199 }
200
201 sub unknown_feature {
202     my $feature = shift;
203     croak(sprintf('Feature "%s" is not supported by Perl %vd',
204             $feature, $^V));
205 }
206
207 sub unknown_feature_bundle {
208     my $feature = shift;
209     croak(sprintf('Feature bundle "%s" is not supported by Perl %vd',
210             $feature, $^V));
211 }
212
213 sub croak {
214     require Carp;
215     Carp::croak(@_);
216 }
217
218 1;