Home / Alt manpages / perl5161delta(1)

  • perl5161delta(1)
  • User command
  • linux

Audit the Perl 5.16.1 Fixes Before Upgrading an Old Script

An old Perl script behaves oddly after a distro bump, and someone hands you perl5161delta and asks if it explains why. Turn the page into a short upgrade checklist: pull out the fixes relevant to an old application, record the runtime and module versions you are actually testing, and run focused regression checks before touching production. Allow 20 to 30 minutes for a small script, longer if it uses threads, formats, Unicode properties or custom XS modules.

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 the page covers. 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, and 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

5.16.1 is a maintenance release over 5.16.0 with no intentional incompatible changes, but it does document repaired behaviour in a handful of areas that are actually worth your time:

  • 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 one that counts.
  • The re pragma stopped clobbering $_.
  • Several runtime fixes landed together: threaded regular-expression runtime blocks, duplicated scalar filehandles, lvalue return values, __SUB__ in special blocks, and formats using outer lexical variables.

None of that is a new command-line switch: perl5161delta is documentation, and 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, which 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 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 tell you 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 above. It keeps the audit small and stops you 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 whatever search tool the project already uses. Review matches rather than mechanically changing them.

  • Threaded programs: run the existing test suite with threads enabled, plus tests for regular-expression code blocks and calls to caller.
  • Code using formats or __SUB__: add a minimal test exercising the feature during BEGIN or END, then compare output and exit status.
  • 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; it does not prescribe a universal test harness.

5. Treat the module versions as part of the upgrade

Upgrading the interpreter alone does not guarantee the versions the release note describes. The page specifically names Scalar::Util and List::Util, and identifies B::Deparse separately. Capture the versions from the interpreter you will actually 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.

Recovery

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

  • Recorded exact versions: the Perl executable, interpreter version and relevant module versions.
  • Read the right boundary: 5.16.0 to 5.16.1, not treating perl5161delta as an executable upgrade tool.
  • Added focused regression tests for tr///, re, threads, formats, filehandles and special blocks that your code actually uses.
  • Passed on the candidate runtime and stored the output with the deployment record.
  • Kept a rollback path with the previous interpreter or deployment artefact still available.