Home / Alt manpages / perl5360delta(1)

  • perl5360delta(1)
  • User command
  • linux

Try Perl 5.36's New Syntax and Safer Defaults

Perl 5.36 quietly tightened a few defaults and added syntax worth trying before you rely on it in production code. In about 15 minutes you will test the 5.36 feature bundle, write a subroutine with a real signature, try the new -g whole-input flag, and see which of the newer features are still experimental. Every example here is read-only and leaves nothing behind.

This guide follows perl5360delta(1), the release note for Perl 5.36.0. The manpage installed on this machine comes from perl-doc version 5.38.2-3.2ubuntu0.6 and is rendered for Perl 5.38.2, so the examples check out locally, but the document itself only describes what 5.36.0 added, not everything the later interpreter picked up since.

1. Check the interpreter before changing code

Start by recording which Perl your shell will actually run:

$ command -v perl
/usr/bin/perl
$ perl -e 'printf "%vd\n", $^V'
v5.38.2

The release note compares 5.36.0 with 5.34.0. A later Perl normally keeps these features, but it can also change experimental behaviour underneath you. If a deployment must stay on 5.36 semantics, check the interpreter in that actual deployment rather than trusting whatever your workstation happens to have installed.

Checkpoint

The version command should print the interpreter that will run your script. Wrong path or wrong version means stop and fix the environment first, not install another Perl into a shared system just to follow along.

2. Turn on the 5.36 feature bundle

Put use v5.36; near the top of any script that needs the release's language defaults:

use v5.36;

sub add ($x, $y) {
    return $x + $y;
}

print add(2, 3), "\n";

Or skip the source file and pass the same code straight to -e:

$ perl -e 'use v5.36; sub add ($x, $y) { $x + $y }; print add(2, 3), "\n"'
5
  • Signatures are stable in this bundle, and so is the isa operator.
  • Warnings turn on automatically.
  • indirect and multidimensional features turn off. Think of it as stricter language defaults, not a substitute for actually reviewing the code you are upgrading.

A signature is not a type declaration: $x and $y still hold ordinary Perl values, the example only adds positional argument binding. Do not mix a signature with @_ or $_[0] while you are upgrading. The 5.36 release note flags access to that legacy argument array inside a signatured subroutine as experimental, with its own warning category.

3. Use -g when a filter needs the whole input

Perl 5.36 adds -g as a shorter alias for -0777. It undefines the input record separator, so a filter reads the entire input as one string instead of chewing through it line by line.

$ printf 'alpha\nbeta\n' | perl -g -pe 's/\n/|/g'
alpha|beta|

The older spelling gives you the identical result:

$ printf 'alpha\nbeta\n' | perl -0777 -pe 's/\n/|/g'
alpha|beta|

Warning

This is handy for a deliberately small whole-document transform, but it is not a free performance win. The input has to fit in memory as one record. Never point a -g one-liner at an unbounded log, a device stream or a user-uploaded file without an explicit size limit. For large input, use a streaming design instead.

Checkpoint

Both commands above should produce one transformed string. If your filter relies on per-line state, do not swap its normal record handling for -g.

4. Try the new builtin functions carefully

Perl 5.36 adds the core builtin module with functions like reftype, trim, indexed, true, false, is_bool, weaken, blessed, ceil and floor. The whole module is experimental in this release, so you opt in knowingly and expect warnings by default.

$ perl -we 'use v5.36; use builtin "reftype"; print builtin::reftype([]), "\n"'
Built-in function 'builtin::reftype' is experimental at -e line 1.
ARRAY

That warning is doing its job during evaluation. Suppressing it is a local decision, not proof the interface is stable:

use v5.36;
use builtin 'reftype';
no warnings 'experimental::builtin';

print reftype([]), "\n";

Use the documented lexical import form when you want a short name, and keep experimental calls behind a small interface in application code so a future Perl upgrade only needs one place to check. Do not treat builtin::true and builtin::false as a strict Boolean type system: Perl values stay flexible even though the new Boolean tracking preserves their Boolean nature.

5. Treat defer, try and multi-value loops as experiments

The release also adds several experimental syntax features:

  • defer blocks run when their enclosing scope exits, after execution reaches the block. They will not run if control leaves the scope before the declaration is reached, and they cannot be escaped with return, goto or loop control.
  • try/catch can now have a finally block.
  • Multi-value iteration such as for my ($key, $value) (%hash) is marked experimental too, under the experimental::for_list warning.
$ perl -we 'use v5.36; use feature "defer"; no warnings "experimental::defer"; { defer { print "cleanup\n" }; print "body\n" }'
body
cleanup

That restriction on escaping a defer block matters when you adapt cleanup code: test the control-flow paths rather than assuming it behaves like a destructor.

$ perl -we 'use v5.36; use feature "try"; no warnings "experimental::try"; try { die "bad\n" } catch ($e) { print "caught:$e" } finally { print "finally\n" }'
caught:bad
finally

Do not ship any of these constructs into a compatibility-sensitive module without testing the oldest Perl you claim to support.

6. Check upgrade traps before committing

A physically empty sort is now a compile-time error. Both of these forms stop being a harmless empty list in 5.36:

@items = sort;      # compile-time error in 5.36
@items = sort ();   # compile-time error in 5.36

Use an explicit empty list if that is what the code actually means, or give sort the real list. Compile the whole program in CI: a runtime test that never touches the affected branch will not catch a compile-time error.

Also review nested version declarations. After use v5.11 or later, a later use v5.8 emits a deprecation warning. If genuinely different language versions must coexist, isolate them in separate lexical blocks; that is usually a sign the upgrade needs a clearer module boundary anyway.

Done means

  • Verified the Perl executable and version used by the test.
  • Compiled a signatured subroutine under use v5.36 and got the expected result.
  • Understood -g as an all-in-one-record read, used only on bounded data.
  • Kept experimental features visible: builtin, defer, try and multi-value loops all still flagged and tested.
  • Checked for empty sort calls and problematic nested use VERSION declarations.