Audit the Perl 5.16.1 fixes before upgrading an old script
You will turn perl5161delta into a short upgrade checklist: identify the fixes relevant to an old Perl application, record the runtime and module versions you are actually testing, and run focused regression checks before changing production. Allow 20 to 30 minutes for a small script, longer if it uses threads, formats, Unicode properties or custom XS modules.
The route
Jump straight to the step you need, or tick off Done means at the end.
This is a release-note guide, not a recipe for installing Perl. The installed manpage describes the change from Perl 5.16.0 to 5.16.1. On this machine, the perl-doc package is version 5.38.2-3.2ubuntu0.6, so the local interpreter is newer than the release covered by the page. That distinction matters: a current interpreter can show the repaired behaviour, but it cannot prove that a particular 5.16.0 binary had the bug.
1. Record the runtime you are testing
Start with read-only checks. Keep this output beside the test results so a later comparison does not lose the version context:
$ command -v perl
/usr/bin/perl
$ perl -v
This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux-gnu-thread-multi
$ perl -MScalar::Util -MList::Util -MB::Deparse -e 'printf "Scalar::Util %s\nList::Util %s\nB::Deparse %s\n", $Scalar::Util::VERSION, $List::Util::VERSION, $B::Deparse::VERSION'
Scalar::Util 1.63
List::Util 1.63
B::Deparse 1.74
Checkpoint: if the first command resolves to an unexpected Perl, stop and fix PATH or invoke the intended absolute path. Do not compare a system Perl with a separately installed interpreter by looking only at the perl command name.
2. Read the change boundary
Display the relevant sections of the installed document:
$ man perl5161delta
The page says that 5.16.1 is a maintenance release over 5.16.0. It lists no intentional incompatible changes. It does, however, document repaired behaviour in several areas. The most operationally useful groups are:
- Scalar::Util and List::Util moved from 1.23 to 1.25, including a fix for an off-by-two error in Scalar-List-Util.
- B::Deparse moved from 1.14 to 1.14_01, removing an uninitialised warning.
- A
tr///regression was corrected: when a search character is repeated, the first occurrence is the meaningful one. - The
repragma stopped clobbering$_. - Threaded regular-expression runtime blocks, duplicated scalar filehandles, lvalue return values,
__SUB__in special blocks and formats using outer lexical variables received fixes.
Do not read this as a list of new command-line switches. perl5161delta is documentation; it accepts no option that upgrades Perl or changes a program. The document also records a Windows build fix involving glob and a VMS header-installation change. Those matter when building or extending Perl on those platforms, not when running an ordinary Linux script.
3. Add a regression check for repeated translation characters
If an application relies on tr///, make the intended mapping explicit in a small test. The release note says that only the first mapping for a repeated search character should count:
$ perl -e '$_ = "a"; tr/aa/xy/; print "$_\n"'
x
Checkpoint: the expected output is x, not y. This command changes only a process-local scalar and exits. Put the equivalent assertion in the application's test suite rather than depending on a manual terminal check:
use strict;
use warnings;
my $value = 'a';
$value =~ tr/aa/xy/;
die "unexpected tr/// result: $value\n" unless $value eq 'x';
Run it with the oldest supported Perl and the candidate Perl. A passing result on 5.38.2 confirms the expected modern semantics; it does not identify which historical binary introduced or fixed the regression.
4. Check code that depends on the repaired areas
Search the application before writing tests for every bullet. This keeps the audit small and avoids spending time on fixes your code cannot exercise:
$ rg -n 'tr/|use re|qr/|threads|__SUB__|format|open.*\|&|Scalar::Util|List::Util|B::Deparse' /path/to/project
Replace /path/to/project with a real source directory. If rg is unavailable, use the project's normal search tool. Review matches rather than mechanically changing them.
For threaded programs, run the existing test suite with threads enabled and include tests for regular-expression code blocks and calls to caller. For code using formats or __SUB__, add a minimal test that exercises the feature during BEGIN or END, then compare output and exit status. For filehandle duplication, verify both the duplicate handle's contents and the original handle's position. These are application checks: the manpage names the repaired failure modes but does not prescribe a universal test harness.
5. Treat the module versions as part of the upgrade
Do not assume that upgrading the interpreter alone gives the versions described by the release note. The page specifically names Scalar::Util and List::Util, and identifies B::Deparse separately. Capture the versions from the interpreter you will deploy:
$ perl -MScalar::Util -MList::Util -MB::Deparse -e 'print join("\n", $Scalar::Util::VERSION, $List::Util::VERSION, $B::Deparse::VERSION), "\n"'
1.63
1.63
1.74
Compare this with the target host, not just your development machine. If an old application has a private library path, inspect that path as well: @INC can select a different module copy from the one you expected. Use perl -V when you need the complete build and library configuration. Do not overwrite system modules by hand; use the operating system's package mechanism or the deployment method already approved for the application.
6. Make the change reversible
Run the regression suite and a representative read-only workload before switching service traffic. Save the old interpreter path, package versions and test output. The manpage describes bug fixes, not a migration rollback mechanism.
If the candidate fails, switch the service back to the previously recorded interpreter or restore the previous deployment artefact according to your normal release process. Do not remove the old Perl while the rollback depends on it. No command in this guide needs sudo; package installation, service changes and boot configuration are deliberately outside its scope.
Done means
- You recorded the exact Perl executable, interpreter version and relevant module versions.
- You read the 5.16.0 to 5.16.1 boundary instead of treating
perl5161deltaas an executable upgrade tool. - Relevant uses of
tr///,re, threads, formats, filehandles and special blocks have focused regression tests. - The tests pass on the candidate runtime and their output is stored with the deployment record.
- The previous interpreter or deployment artefact remains available for an explicit rollback.