X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/d5da2b2b853f7efb706db6244125b8b6ddad5942..f240c685c914970dc8ffec926f02d6048831bc09:/lib/feature.pm diff --git a/lib/feature.pm b/lib/feature.pm index f8a9078..ec9fff7 100644 --- a/lib/feature.pm +++ b/lib/feature.pm @@ -1,32 +1,61 @@ +# -*- buffer-read-only: t -*- +# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! +# This file is built by regen/feature.pl. +# Any changes made here will be lost! + package feature; -our $VERSION = '1.18'; +our $VERSION = '1.42'; -# (feature name) => (internal name, used in %^H) -my %feature = ( +our %feature = ( + fc => 'feature_fc', + say => 'feature_say', + state => 'feature_state', switch => 'feature_switch', - say => "feature_say", - state => "feature_state", - unicode_strings => "feature_unicode", + bitwise => 'feature_bitwise', + evalbytes => 'feature_evalbytes', + postderef => 'feature_postderef', + array_base => 'feature_arybase', + signatures => 'feature_signatures', + current_sub => 'feature___SUB__', + refaliasing => 'feature_refaliasing', + lexical_subs => 'feature_lexsubs', + postderef_qq => 'feature_postderef_qq', + unicode_eval => 'feature_unieval', + unicode_strings => 'feature_unicode', +); + +our %feature_bundle = ( + "5.10" => [qw(array_base say state switch)], + "5.11" => [qw(array_base say state switch unicode_strings)], + "5.15" => [qw(current_sub evalbytes fc say state switch unicode_eval unicode_strings)], + "5.23" => [qw(current_sub evalbytes fc postderef_qq say state switch unicode_eval unicode_strings)], + "all" => [qw(array_base bitwise current_sub evalbytes fc lexical_subs postderef postderef_qq refaliasing say signatures state switch unicode_eval unicode_strings)], + "default" => [qw(array_base)], ); +$feature_bundle{"5.12"} = $feature_bundle{"5.11"}; +$feature_bundle{"5.13"} = $feature_bundle{"5.11"}; +$feature_bundle{"5.14"} = $feature_bundle{"5.11"}; +$feature_bundle{"5.16"} = $feature_bundle{"5.15"}; +$feature_bundle{"5.17"} = $feature_bundle{"5.15"}; +$feature_bundle{"5.18"} = $feature_bundle{"5.15"}; +$feature_bundle{"5.19"} = $feature_bundle{"5.15"}; +$feature_bundle{"5.20"} = $feature_bundle{"5.15"}; +$feature_bundle{"5.21"} = $feature_bundle{"5.15"}; +$feature_bundle{"5.22"} = $feature_bundle{"5.15"}; +$feature_bundle{"5.24"} = $feature_bundle{"5.23"}; +$feature_bundle{"5.9.5"} = $feature_bundle{"5.10"}; + +our $hint_shift = 26; +our $hint_mask = 0x1c000000; +our @hint_bundles = qw( default 5.10 5.11 5.15 5.23 ); + # This gets set (for now) in $^H as well as in %^H, # for runtime speed of the uc/lc/ucfirst/lcfirst functions. # See HINT_UNI_8_BIT in perl.h. our $hint_uni8bit = 0x00000800; -# NB. the latest bundle must be loaded by the -E switch (see toke.c) - -my %feature_bundle = ( - "5.10" => [qw(switch say state)], - "5.11" => [qw(switch say state unicode_strings)], - "5.12" => [qw(switch say state unicode_strings)], - "5.13" => [qw(switch say state unicode_strings)], -); - -# special case -$feature_bundle{"5.9.5"} = $feature_bundle{"5.10"}; - # TODO: # - think about versioned features (use feature switch => 2) @@ -36,29 +65,33 @@ feature - Perl pragma to enable new features =head1 SYNOPSIS - use feature qw(switch say); + use feature qw(say switch); given ($foo) { - when (1) { say "\$foo == 1" } - when ([2,3]) { say "\$foo == 2 || \$foo == 3" } - when (/^a[bc]d$/) { say "\$foo eq 'abd' || \$foo eq 'acd'" } - when ($_ > 100) { say "\$foo > 100" } - default { say "None of the above" } + when (1) { say "\$foo == 1" } + when ([2,3]) { say "\$foo == 2 || \$foo == 3" } + when (/^a[bc]d$/) { say "\$foo eq 'abd' || \$foo eq 'acd'" } + when ($_ > 100) { say "\$foo > 100" } + default { say "None of the above" } } use feature ':5.10'; # loads all features available in perl 5.10 + use v5.10; # implicitly loads :5.10 feature bundle + =head1 DESCRIPTION It is usually impossible to add new syntax to Perl without breaking -some existing programs. This pragma provides a way to minimize that +some existing programs. This pragma provides a way to minimize that risk. New syntactic constructs, or new semantic meanings to older constructs, can be enabled by C, and will be parsed -only when the appropriate feature pragma is in scope. +only when the appropriate feature pragma is in scope. (Nevertheless, the +C prefix provides access to all Perl keywords, regardless of this +pragma.) =head2 Lexical effect Like other pragmas (C, for example), features have a lexical -effect. C will only make the feature "foo" available +effect. C will only make the feature "foo" available from that point to the end of the enclosing block. { @@ -69,7 +102,7 @@ from that point to the end of the enclosing block. =head2 C -Features can also be turned off by using C. This too +Features can also be turned off by using C. This too has lexical effect. use feature 'say'; @@ -80,72 +113,313 @@ has lexical effect. } say "Yet it is here."; -C with no features specified will turn off all features. +C with no features specified will reset to the default group. To +disable I features (an unusual request!) use C. -=head2 The 'switch' feature - -C tells the compiler to enable the Perl 6 -given/when construct. - -See L for details. +=head1 AVAILABLE FEATURES =head2 The 'say' feature -C tells the compiler to enable the Perl 6 +C tells the compiler to enable the Perl 6 style C function. See L for details. -=head2 the 'state' feature +This feature is available starting with Perl 5.10. + +=head2 The 'state' feature C tells the compiler to enable C variables. See L for details. -=head2 the 'unicode_strings' feature +This feature is available starting with Perl 5.10. + +=head2 The 'switch' feature + +B: Because the L is +experimental, Perl will warn when you use this feature, unless you have +explicitly disabled the warning: + + no warnings "experimental::smartmatch"; + +C tells the compiler to enable the Perl 6 +given/when construct. + +See L for details. + +This feature is available starting with Perl 5.10. + +=head2 The 'unicode_strings' feature + +C tells the compiler to use Unicode rules +in all string operations executed within its scope (unless they are also +within the scope of either C or C). The same applies +to all regular expressions compiled within the scope, even if executed outside +it. It does not change the internal representation of strings, but only how +they are interpreted. + +C tells the compiler to use the traditional +Perl rules wherein the native character set rules is used unless it is +clear to Perl that Unicode is desired. This can lead to some surprises +when the behavior suddenly changes. (See +L for details.) For this reason, if you are +potentially using Unicode in your program, the +C subpragma is B recommended. + +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. + +=head2 The 'unicode_eval' and 'evalbytes' features + +Under the C feature, Perl's C function, when passed a +string, will evaluate it as a string of characters, ignoring any +C declarations. C exists to declare the encoding of +the script, which only makes sense for a stream of bytes, not a string of +characters. Source filters are forbidden, as they also really only make +sense on strings of bytes. Any attempt to activate a source filter will +result in an error. + +The C feature enables the C keyword, which evaluates +the argument passed to it as a string of bytes. It dies if the string +contains any characters outside the 8-bit range. Source filters work +within C: they apply to the contents of the string being +evaluated. + +Together, these two features are intended to replace the historical C +function, which has (at least) two bugs in it, that cannot easily be fixed +without breaking existing programs: + +=over + +=item * + +C behaves differently depending on the internal encoding of the +string, sometimes treating its argument as a string of bytes, and sometimes +as a string of characters. + +=item * + +Source filters activated within C leak out into whichever I +scope is currently being compiled. To give an example with the CPAN module +L: + + BEGIN { eval "use Semi::Semicolons; # not filtered here " } + # filtered here! + +C fixes that to work the way one would expect: + + use feature "evalbytes"; + BEGIN { evalbytes "use Semi::Semicolons; # filtered " } + # not filtered + +=back + +These two features are available starting with Perl 5.16. + +=head2 The 'current_sub' feature + +This provides the C<__SUB__> token that returns a reference to the current +subroutine or C outside of a subroutine. + +This feature is available starting with Perl 5.16. + +=head2 The 'array_base' feature + +This feature supports the legacy C<$[> variable. See L and +L. It is on by default but disabled under C (see +L, below). + +This feature is available under this name starting with Perl 5.16. In +previous versions, it was simply on all the time, and this pragma knew +nothing about it. + +=head2 The 'fc' feature + +C tells the compiler to enable the C function, +which implements Unicode casefolding. + +See L for details. + +This feature is available from Perl 5.16 onwards. + +=head2 The 'lexical_subs' feature + +B: This feature is still experimental and the implementation may +change in future versions of Perl. For this reason, Perl will +warn when you use the feature, unless you have explicitly disabled the +warning: + + no warnings "experimental::lexical_subs"; + +This enables declaration of subroutines via C, C +and C syntax. See L for details. -C tells the compiler to treat -all strings outside of C and C as Unicode. It is -available starting with Perl 5.11.3, but is not fully implemented. +This feature is available from Perl 5.18 onwards. -See L for details. +=head2 The 'postderef' and 'postderef_qq' features + +The 'postderef_qq' feature extends the applicability of L so that postfix array +and scalar dereference are available in double-quotish interpolations. For +example, it makes the following two statements equivalent: + + my $s = "[@{ $h->{a} }]"; + my $s = "[$h->{a}->@*]"; + +This feature is available from Perl 5.20 onwards. In Perl 5.20 and 5.22, it +was classed as experimental, and Perl emitted a warning for its +usage, except when explicitly disabled: + + no warnings "experimental::postderef"; + +As of Perl 5.24, use of this feature no longer triggers a warning, though +the C warning category still exists (for +compatibility with code that disables it). + +The 'postderef' feature was used in Perl 5.20 and Perl 5.22 to enable +postfix dereference syntax outside double-quotish interpolations. In those +versions, using it triggered the C warning in the +same way as the 'postderef_qq' feature did. As of Perl 5.24, this syntax is +not only no longer experimental, but it is enabled for all Perl code, +regardless of what feature declarations are in scope. + +=head2 The 'signatures' feature + +B: This feature is still experimental and the implementation may +change in future versions of Perl. For this reason, Perl will +warn when you use the feature, unless you have explicitly disabled the +warning: + + no warnings "experimental::signatures"; + +This enables unpacking of subroutine arguments into lexical variables +by syntax such as + + sub foo ($left, $right) { + return $left + $right; + } + +See L for details. + +This feature is available from Perl 5.20 onwards. + +=head2 The 'refaliasing' feature + +B: This feature is still experimental and the implementation may +change in future versions of Perl. For this reason, Perl will +warn when you use the feature, unless you have explicitly disabled the +warning: + + no warnings "experimental::refaliasing"; + +This enables aliasing via assignment to references: + + \$a = \$b; # $a and $b now point to the same scalar + \@a = \@b; # to the same array + \%a = \%b; + \&a = \&b; + foreach \%hash (@array_of_hash_refs) { + ... + } + +See L for details. + +This feature is available from Perl 5.22 onwards. + +=head2 The 'bitwise' feature + +B: This feature is still experimental and the implementation may +change in future versions of Perl. For this reason, Perl will +warn when you use the feature, unless you have explicitly disabled the +warning: + + no warnings "experimental::bitwise"; + +This makes the four standard bitwise operators (C<& | ^ ~>) treat their +operands consistently as numbers, and introduces four new dotted operators +(C<&. |. ^. ~.>) that treat their operands consistently as strings. The +same applies to the assignment variants (C<&= |= ^= &.= |.= ^.=>). + +See L for details. + +This feature is available from Perl 5.22 onwards. =head1 FEATURE BUNDLES -It's possible to load a whole slew of features in one go, using -a I. The name of a feature bundle is prefixed with -a colon, to distinguish it from an actual feature. At present, the -only feature bundle is C which is equivalent -to C. +It's possible to load multiple features together, using +a I. The name of a feature bundle is prefixed with +a colon, to distinguish it from an actual feature. + + use feature ":5.10"; + +The following feature bundles are available: + + bundle features included + --------- ----------------- + :default array_base -Specifying sub-versions such as the C<0> in C<5.10.0> in feature bundles has -no effect: feature bundles are guaranteed to be the same for all sub-versions. + :5.10 say state switch array_base + + :5.12 say state switch unicode_strings array_base + + :5.14 say state switch unicode_strings array_base + + :5.16 say state switch unicode_strings + unicode_eval evalbytes current_sub fc + + :5.18 say state switch unicode_strings + unicode_eval evalbytes current_sub fc + + :5.20 say state switch unicode_strings + unicode_eval evalbytes current_sub fc + + :5.22 say state switch unicode_strings + unicode_eval evalbytes current_sub fc + + :5.24 say state switch unicode_strings + unicode_eval evalbytes current_sub fc + postderef_qq + +The C<:default> bundle represents the feature set that is enabled before +any C or C declaration. + +Specifying sub-versions such as the C<0> in C<5.14.0> in feature bundles has +no effect. Feature bundles are guaranteed to be the same for all sub-versions. + + use feature ":5.14.0"; # same as ":5.14" + use feature ":5.14.1"; # same as ":5.14" =head1 IMPLICIT LOADING -There are two ways to load the C pragma implicitly : +Instead of loading feature bundles by name, it is easier to let Perl do +implicit loading of a feature bundle for you. + +There are two ways to load the C pragma implicitly: =over 4 =item * -By using the C<-E> switch on the command-line instead of C<-e>. It enables -all available features in the main compilation unit (that is, the one-liner.) +By using the C<-E> switch on the Perl command-line instead of C<-e>. +That will enable the feature bundle for that version of Perl in the +main compilation unit (that is, the one-liner that follows C<-E>). =item * -By requiring explicitly a minimal Perl version number for your program, with -the C construct, and when the version is higher than or equal to -5.10.0. That is, +By explicitly requiring a minimum Perl version number for your program, with +the C construct. That is, - use 5.10.0; + use v5.10.0; will do an implicit + no feature ':all'; use feature ':5.10'; -and so on. Note how the trailing sub-version is automatically stripped from the +and so on. Note how the trailing sub-version +is automatically stripped from the version. But to avoid portability warnings (see L), you may prefer: @@ -154,79 +428,87 @@ But to avoid portability warnings (see L), you may prefer: with the same effect. +If the required version is older than Perl 5.10, the ":default" feature +bundle is automatically loaded instead. + =back =cut sub import { - my $class = shift; - if (@_ == 0) { - croak("No features specified"); - } - 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'; + shift; + + if (!@_) { + croak("No features specified"); } + + __common(1, @_); } sub unimport { - my $class = shift; + shift; - # A bare C should disable *all* features + # A bare C should reset to the default bundle if (!@_) { - delete @^H{ values(%feature) }; - $^H &= ~ $hint_uni8bit; + $^H &= ~($hint_uni8bit|$hint_mask); return; } - 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); + __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'; } - else { - delete $^H{$feature{$name}}; + } + 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); + } + 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'; - } + } } } sub unknown_feature { my $feature = shift; croak(sprintf('Feature "%s" is not supported by Perl %vd', - $feature, $^V)); + $feature, $^V)); } sub unknown_feature_bundle { my $feature = shift; croak(sprintf('Feature bundle "%s" is not supported by Perl %vd', - $feature, $^V)); + $feature, $^V)); } sub croak { @@ -235,3 +517,5 @@ sub croak { } 1; + +# ex: set ro: