current_sub => '__SUB__',
unicode_eval => 'unieval',
unicode_strings => 'unicode',
+ fc => 'fc',
);
# NOTE: If a feature is ever enabled in a non-contiguous range of Perl
# versions, any code below that uses %BundleRanges will have to
# be changed to account.
+# 5.odd implies the next 5.even, but an explicit 5.even can override it.
my %feature_bundle = (
+ all => [ keys %feature ],
default => [qw(array_base)],
"5.9.5" => [qw(say state switch array_base)],
"5.10" => [qw(say state switch array_base)],
"5.11" => [qw(say state switch unicode_strings array_base)],
- "5.12" => [qw(say state switch unicode_strings array_base)],
"5.13" => [qw(say state switch unicode_strings array_base)],
- "5.14" => [qw(say state switch unicode_strings array_base)],
"5.15" => [qw(say state switch unicode_strings unicode_eval
- evalbytes current_sub)],
- "5.16" => [qw(say state switch unicode_strings unicode_eval
- evalbytes current_sub)],
+ evalbytes current_sub fc)],
+ "5.17" => [qw(say state switch unicode_strings unicode_eval
+ evalbytes current_sub fc)],
);
###########################################################################
# More data generated from the above
+for (keys %feature_bundle) {
+ next unless /^5\.(\d*[13579])\z/;
+ $feature_bundle{"5.".($1+1)} ||= $feature_bundle{$_};
+}
+
my %UniqueBundles; # "say state switch" => 5.10
my %Aliases; # 5.12 => 5.11
for( sort keys %feature_bundle ) {
length sprintf "%b", scalar keys %UniqueBundles;
$bits =~ /1{$bits_needed}/
or die "Not enough bits (need $bits_needed)"
- . " in $bits (binary for $hex):\n\n$_\n";
+ . " in $bits (binary for $hex):\n\n$_\n ";
}
if ($Uni8Bit && $HintMask) { last }
}
#define CURRENT_HINTS \
(PL_curcop == &PL_compiling ? PL_hints : PL_curcop->cop_hints)
-#define CURRENT_FEATURE_BUNDLE (CURRENT_HINTS >> HINT_FEATURE_SHIFT)
+#define CURRENT_FEATURE_BUNDLE \
+ ((CURRENT_HINTS & HINT_FEATURE_MASK) >> HINT_FEATURE_SHIFT)
+/* Avoid using ... && Perl_feature_is_enabled(...) as that triggers a bug in
+ the HP-UX cc on PA-RISC */
#define FEATURE_IS_ENABLED(name) \
((CURRENT_HINTS \
& HINT_LOCALIZE_HH) \
- && Perl_feature_is_enabled(aTHX_ STR_WITH_LEN(name)))
+ ? Perl_feature_is_enabled(aTHX_ STR_WITH_LEN(name)) : FALSE)
/* The longest string we pass in. */
EOH
__END__
package feature;
-our $VERSION = '1.25';
+our $VERSION = '1.29';
FEATURES
}
say "Yet it is here.";
-C<no feature> with no features specified will turn off all features.
+C<no feature> with no features specified will reset to the default group. To
+disable I<all> features (an unusual request!) use C<no feature ':all'>.
=head1 AVAILABLE FEATURES
in all string operations executed within its scope (unless they are also
within the scope of either C<use locale> or C<use bytes>). The same applies
to all regular expressions compiled within the scope, even if executed outside
-it.
+it. It does not change the internal representation of strings, but only how
+they are interpreted.
C<no feature 'unicode_strings'> tells the compiler to use the traditional
Perl semantics wherein the native character set semantics is used unless it is
potentially using Unicode in your program, the
C<use feature 'unicode_strings'> subpragma is B<strongly> recommended.
-This feature is available starting with Perl 5.12, but was not fully
-implemented until Perl 5.14.
+This feature is available starting with Perl 5.12; was almost fully
+implemented in Perl 5.14; and extended in Perl 5.16 to cover C<quotemeta>.
=head2 The 'unicode_eval' and 'evalbytes' features
previous versions, it was simply on all the time, and this pragma knew
nothing about it.
+=head2 The 'fc' feature
+
+C<use feature 'fc'> tells the compiler to enable the C<fc> function,
+which implements Unicode casefolding.
+
+See L<perlfunc/fc> for details.
+
+This feature is available from Perl 5.16 onwards.
+
=head1 FEATURE BUNDLES
It's possible to load multiple features together, using
will do an implicit
- no feature;
+ no feature ':all';
use feature ':5.10';
and so on. Note how the trailing sub-version
=cut
-sub current_bundle {
- my $bundle_number = $^H & $hint_mask;
- return if $bundle_number == $hint_mask;
- return $feature_bundle{@hint_bundles[$bundle_number >> $hint_shift]};
-}
-
-sub normalise_hints {
- # Delete any keys that may be left over from last time.
- delete @^H{ values(%feature) };
- $^H |= $hint_mask;
- for (@{+shift}) {
- $^H{$feature{$_}} = 1;
- $^H |= $hint_uni8bit if $_ eq 'unicode_strings';
- }
-}
-
sub import {
my $class = shift;
- if (@_ == 0) {
+
+ if (!@_) {
croak("No features specified");
}
- if (my $features = current_bundle) {
- # Features are enabled implicitly via bundle hints.
- normalise_hints $features;
- }
- while (@_) {
- my $name = shift(@_);
- if (substr($name, 0, 1) eq ":") {
- my $v = substr($name, 1);
- if (!exists $feature_bundle{$v}) {
- $v =~ s/^([0-9]+)\.([0-9]+).[0-9]+$/$1.$2/;
- if (!exists $feature_bundle{$v}) {
- unknown_feature_bundle(substr($name, 1));
- }
- }
- unshift @_, @{$feature_bundle{$v}};
- next;
- }
- if (!exists $feature{$name}) {
- unknown_feature($name);
- }
- $^H{$feature{$name}} = 1;
- $^H |= $hint_uni8bit if $name eq 'unicode_strings';
- }
+
+ __common(1, @_);
}
sub unimport {
my $class = shift;
- if (my $features = current_bundle) {
- # Features are enabled implicitly via bundle hints.
- normalise_hints $features;
- }
-
- # A bare C<no feature> should disable *all* features
+ # A bare C<no feature> should reset to the default bundle
if (!@_) {
- delete @^H{ values(%feature) };
- $^H &= ~ $hint_uni8bit;
- return;
+ $^H &= ~($hint_uni8bit|$hint_mask);
+ return;
}
+ __common(0, @_);
+}
+
+
+sub __common {
+ my $import = shift;
+ my $bundle_number = $^H & $hint_mask;
+ my $features = $bundle_number != $hint_mask
+ && $feature_bundle{$hint_bundles[$bundle_number >> $hint_shift]};
+ if ($features) {
+ # Features are enabled implicitly via bundle hints.
+ # Delete any keys that may be left over from last time.
+ delete @^H{ values(%feature) };
+ $^H |= $hint_mask;
+ for (@$features) {
+ $^H{$feature{$_}} = 1;
+ $^H |= $hint_uni8bit if $_ eq 'unicode_strings';
+ }
+ }
while (@_) {
my $name = shift;
if (substr($name, 0, 1) eq ":") {
unshift @_, @{$feature_bundle{$v}};
next;
}
- if (!exists($feature{$name})) {
+ if (!exists $feature{$name}) {
unknown_feature($name);
}
- else {
+ if ($import) {
+ $^H{$feature{$name}} = 1;
+ $^H |= $hint_uni8bit if $name eq 'unicode_strings';
+ } else {
delete $^H{$feature{$name}};
$^H &= ~ $hint_uni8bit if $name eq 'unicode_strings';
}