NAME
Perl::Version::Bumper - Update use VERSION on any Perl code
SYNOPSIS
use Perl::Version::Bumper;
my $perv = Perl::Version::Bumper->new( version => 'v5.36' );
# bump a PPI::Document
my $bumped_ppi = $perv->bump_ppi($ppi_doc);
# bump source code
my $bumped_code = $perv->bump($code);
# bump the source of a file
$perv->bump_file($filename);
# safe versions (check the result compiles)
my $bumped_ppi = $perv->bump_ppi_safely($ppi_doc);
my $bumped_code = $perv->bump_safely($code);
$perv->bump_file_safely( $filename, $version_limit );
DESCRIPTION
Perl::Version::Bumper can update Perl code to make it declare it uses a more recent version of the Perl language by way of use VERSION.
It takes care of removing unnecessary loading of feature and experimental warnings, and adds the use VERSION line at the top of the file (thus encouraging "line 1 semantics").
It also manages the removal of "compatibility" modules when the feature they provide a compatibility layer with is fully supported in the target Perl version.
If the code already declares a Perl version, it can only be bumped to a higher version.
The module exports a few helper functions. These are mostly used by support tools for this distribution, and are not meant for general use.
CONSTRUCTOR
new
my $perv = Perl::Version::Bumper->new( %attributes );
my $perv = Perl::Version::Bumper->new( \%attributes );
Return a new Perl::Version::Bumper object.
ATTRIBUTES
version
The target version to bump to.
Defaults to the stable version less than or equal to the version of the currenly running perl.
The constructor accepts both forms of Perl versions, regular (e.g. v5.36) and floating-point (e.g. 5.036), and will turn it into a string suitable for use VERSION.
To protect against simple mistakes (e.g. passing 5.36 instead of v5.36), the constructor does some sanity checking, and checks that the given version:
is greater than or equal to
v5.10,is lower than the version of the Perl currently running,
is a stable Perl version.
The constructor will also drops any sub-version information (so v5.36.2 will be turned into v5.36).
CLASS METHODS
feature_version
Return the version (in numeric format) of the feature set recognized by this module. It is not possible to bump code over that version.
The current value of feature_version is: 5.040.
feature_data
Return a copy of the internal data structure containing all the information about features. That should only be needed for testing and debugging.
METHODS
version_num
Return the "version" attribute as a number.
bump_ppi
my $bumped_ppi_doc = $perv->bump_ppi($ppi_doc);
Take a PPI::Document as input, and return a new PPI::Document with its declared version bumped to "version".
bump
my $bumped_code = $perv->bump($code);
Take a string containing Perl code as input, bump the declared Perl version in the source code to "version", and return the new source code as a string.
bump_file
$perv->bump_file($filename);
Bump the code of the file argument in-place.
Return a boolean indicating if the file content was modified or not.
SAFE METHODS
The "bump_ppi", "bump" and "bump_file" methods previously described modify the source code they're given, but give no garanties that the updated code will even compile.
To address this issue, "bump_ppi_safely", "bump_safely" and "bump_file_safely" methods work as the regular methods, but will only produce code that actually compiles.
If all attempts fail, the return value is identical to the input value.
Example of a safe bump
The following code uses multidimensional array emulation:
my %h; $h{ 1, 2 } = 3; # same as $foo{"1\x{1c}2"} = 3;
"bump" will produce the following when trying to update it to v5.40:
use v5.40;
my %h; $h{ 1, 2 } = 3; # same as $foo{"1\x{1c}2"} = 3;
Which fails to compile with the following error:
Multidimensional hash lookup is disabled
It's not possible to just bump this code up to v5.40 and expect it to work, because it uses multidimensional array emulation, and the feature that represents this (multidimensional) was disabled in v5.36. This code will in fact fail to compile with all version bundles greater or equal to v5.36.
A safe way to try to bump this code to v5.40 is to try with v5.40, detect it fails to compile, try again with v5.38 and v5.36, which also fail, until we hit v5.34 which compiles just fine (because the multidimensional feature is still enabled in that bundle). Leaving us with the following code:
use v5.34;
my %h; $h{ 1, 2 } = 3; # same as $foo{"1\x{1c}2"} = 3;
The code needs to be updated to not use multidimensional array emulation before it can safely be bumped past version v5.34.
Process of a safe bump
The process for a safe bump is to take some input, and try to compile it. If the compilation fails, return immediately.
Otherwise, continue with the process: bump the content, and try to compile the result. Return as soon as compilation succeeds.
If compilation fails, decrease the target Perl version number, bump the content to that version, and try to compile the result again. Keep decreasing the target version, all the way back to the currently declared version in the document, or version_limit, whichever is more recent. Give up after the last compilation failure.
Options for a safe bump
All the methods below take one input argument (a PPI::Document, a string of code or a filename) and one optional hash reference for options.
The possible options are:
- version_limit
-
The version at which to stop decreasing the target version. Defaults to
v5.10. - env
-
A hash reference of key/value pairs for environment variables to be set when trying to compile the bumped code.
bump_ppi_safely
my $bumped_ppi = $perv->bump_ppi_safely( $ppi_doc, \%options );
Safely bump the source code in the given PPI::Document.
The return value is a new PPI::Document containing the result of the "safe bump" (its content might be the same as the original if there's no safe way to bump the code).
bump_safely
my $bumped_code = $perv->bump_safely( $code, \%options );
my ( $bumped_code, $new_version ) = $perv->bump_safely($code);
Safely bump the source code given as a string.
The return value is a string containing the new source code.
bump_file_safely
$perv->bump_file_safely( $filename, \%options );
Safely bump the code in the file argument in-place. The file will not be modified if the code can't be bumped safely.
The return value is undef if the original didn't compile, false if all attempts to bump the file failed, and the actual (numerical) version number the file was bumped to in case of success.
EXPORTS
The following functions can be optionally exported. Be aware that they are mostly meant for internal use of the module and helper scripts.
version_fmt
my $v = version_fmt( $version );
Return the given version (in string, v-string or float format) as a number.
This function will die if the given version is not a plausible Perl version number, i.e. is strictly lower than 5.010.
Note that all the following functions start by normalizing their argument by calling "version_fmt", meaning they will die in the same circumstances.
version_use
my $v = version_use( $version );
Return the given version (in string, v-string or float format) as a string suitable for a use VERSION line.
stable_version
my $s = stable_version( $version );
Return the closest stable version lower or equal to the given version, as a number.
stable_version_inc
my $n = stable_version_inc( $version );
Return the stable version following the given version, as a number.
stable_version_dec
my $p = stable_version_dec( $version );
Return the stable version preceding the given version, as a number.
VERSION UPGRADE ALGORITHM
For a given version number, a feature has three attributes:
- known
-
the perl binary knows about the feature starting from that version.
If it's not known, passing it to
use featurewill die during compilation withFeature "XXX" is not supported by Perl 5.x.y(where 5.x.y is the version of the binary program). - enabled
-
the feature is enabled starting with the corresponding feature bundle (i.e.
use VERSIONwill implicitely enable it). - disabled
-
the feature is disabled starting from the corresponding feature bundle (i.e.
use VERSIONwill implicitely disable it).This is the case for so-called "unfeatures", i.e. constructs that were deemed undesirable and removed from the language (e.g.
indirect,bareword_filehandles, etc.).
If there is more than one use VERSION line in the file, the algorithm will bail out. Otherwise, the previous use VERSION line will be removed, and a new one added at the top of the file (line 1).
The features that were enabled via use feature and are part of the VERSION feature bundle will be removed from the corresponding use feature or use experimental lines. The disabling of the corresponding experimental warnings will be removed.
The features that were disabled via no feature and are disabled as part of the VERSION feature bundle will be removed from the corresponding use feature or use experimental lines.
If compatibility modules (CPAN modules that provide support for the feature in older Perls) were loaded, they will removed if the feature is enabled in the feature bundle for VERSION, or replaced by the corresponding use feature if the feature is known by the corresponding perl binary but not yet enabled by the feature bundle.
When a feature is enabled (or disabled) in the context of a feature version bundle that's less than the version when the feature was known by Perl, the line won't be removed.
For example this line:
use feature 'signatures';
will die with any perl before perl5.20.0, because the binary does not know about the feature itself.
When writing code like this:
use v5.10;
use feature 'signatures';
one is opting into a version of the Perl language that is not described by any specific feature bundle. However, any perl that knows about the signatures feature will know how to run it.
Bumping it to the feature bundle for v5.16, for example, is valid, and will work with any perl that knows about the signatures feature:
use v5.16;
use feature 'signatures';
And so on until v5.36, when the signatures feature was enabled by the corresponding version bundle:
use v5.36;
Finally, some features may imply extra edits:
- bitwise
-
When the
bitwisefeature is enabled, the behaviour of the bitwise operators (&,|,~and^) is modified. If the code makes use of one of them, and the code is moved from a version before v5.28 to a version greater or equal to v5.28, thebitwisefeature will be disabled, and a comment will be added, asking the maintainer to review their use according to thebitwisefeature before removing it. - signatures
-
When signatures are implicitely enabled, any prototypes will be rewritten with the prototype attribute syntax. For example:
sub foo ($@) { ... }will become:
sub foo :prototype($@) { ... } - fc
-
Once
fcis implicitely enabled, All uses ofCORE::fcwill be replaced by a barefc.
Feature/version data table
The following table is used to generate the feature data hash.
It is generated using the bin/build_feature_data.pl script shipped with the distribution.
The keys are:
- known
-
when perl first learnt about the feature
- enabled
-
when the feature was first enabled (may be before it was known)
- disabled
-
when the feature was first disabled
- compat
-
replacement modules for features to be deprecated / added
Different features have different lifecycles:
New features (i.e. additional behaviour that didn't exist in Perl v5.8):
are
knownin the Perl release that introduced themare
enabledeither in the same version (e.g.say,state) or after an "experimental" phase (e.g.signatures,bitwise)once enabled, they are not meant to be
disabledin a later bundle.
Unfeatures, or backwards compatibility features (features that existed in older Perls, but were later deemed undesirable, and scheduled for being eventually disabled or removed):
are
enabledin the:defaultbundle (they were part of the old Perl 5 behaviour) before they are evenknown(a feature that represents them was added to Perl).are meant to be manually disabled (with
no feature), until a later feature bundle eventually disables them by default.
"compat" modules are CPAN modules meant to add support to the feature on perls where it's not available yet. They exist both for new features and backwards compatibility features. The number following the module name in the data structure below is the sum of 1 (if the module has an import method) and -1 (if the module has an unimport method).
5.040 features known enabled disabled compat
say 5.010 5.010 Perl6::Say 1 Say::Compat 1
state 5.010 5.010
switch 5.010 5.010 5.036
unicode_strings 5.012 5.012
array_base 5.016 5.010 5.016
current_sub 5.016 5.016
evalbytes 5.016 5.016
fc 5.016 5.016
unicode_eval 5.016 5.016
lexical_subs 5.018 5.026
postderef 5.020 5.024
postderef_qq 5.020 5.024
signatures 5.020 5.036
refaliasing 5.022
bitwise 5.022 5.028
declared_refs 5.026
indirect 5.032 5.010 5.036 indirect 0
isa 5.032 5.036
multidimensional 5.034 5.010 5.036 multidimensional 0
bareword_filehandles 5.034 5.010 5.038 bareword::filehandles 0
try 5.034 5.040 Feature::Compat::Try 1 Syntax::Feature::Try 0 Syntax::Keyword::Try 0
defer 5.036 Feature::Compat::Defer 1 Syntax::Keyword::Defer 0
extra_paired_delimiters 5.036
class 5.038 Feature::Compat::Class 1
module_true 5.038 5.038
ADDITIONAL INFORMATION ABOUT PERL FEATURES AND CONSTRUCTS
Official documentation
- feature
-
Perl pragma to enable new features.
- perlexperiment
-
A listing of experimental features in Perl.
- experimental
-
This pragma provides an easy and convenient way to enable or disable experimental features.
CPAN Modules
- Syntax::Construct
-
For some new syntactic constructs, there is the "feature pragma". For the rest, there is Syntax::Construct.::
- Perl::MinimumVersion
-
Find a minimum required version of
perlfor Perl code. - Perl::MinimumVersion::Fast
-
Perl::MinimumVersion::Fast is an alternative fast & lightweight implementation of Perl::MinimumVersion.
Other
- https://sheet.shiar.nl/perl
-
The most significant features introduced for recent versions of the Perl scripting language.
ACKNOWLEDGMENT
This software was originally developed at Booking.com. With approval from Booking.com, this software was released as open source, for which the authors would like to express their gratitude.
AUTHOR
Philippe Bruhat (BooK) <book@cpan.org>
COPYRIGHT
Copyright 2024-2026 Philippe Bruhat (BooK), all rights reserved.
LICENSE
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.