Differences from Perl 5#

PetaPerl targets full behavioral compatibility with Perl 5.44: same syntax, same pragmas, same runtime semantics, byte-identical output. The test harness compares every test’s output against a real perl binary, so “works” below means “verified byte-exact”. The differences that remain are deliberate design decisions, catalogued here.

Every claim on this page is re-verified against the current runtime when the page changes; historic limitations that no longer exist are removed rather than annotated.

Intentional Differences#

No XS binary loading#

PetaPerl never loads compiled extension objects (.so files). Instead, the three things XS is used for are served separately:

  • Speed: the core XS module population (List::Util, Scalar::Util, Data::Dumper, Digest::*, Encode, Storable, POSIX, …) ships as native modules inside the binary, and the JIT with auto-parallelization makes pure Perl itself competitive.

  • C libraries: Peta::FFI calls into system libraries without any compilation (see the Cairo binding for a complete example).

  • Pure Perl fallbacks: dists that ship one (most dual-life modules do) simply use it, on a faster interpreter.

A dist that strictly requires its own compiled XS object and offers no fallback will not run. cpan install Some::XS::Module is not a supported path and never will be.

Module loading and @INC#

Three deliberate deviations, all consequences of pperl being one self-contained binary that runs no compiled XS objects:

  • Native modules have absolute priority. A module built into the binary is served by require directly; a same-name .pm on disk can never shadow it, regardless of -I or PERL5LIB. Everything not built in resolves through @INC in normal first-hit-wins order.

  • No architecture directories. Neither the host’s archlib trees nor x86_64-linux-style children of -I/PERL5LIB entries are searched. They exist to hold compiled .so objects and their loaders; skipping them is what lets library trees built by a real perl (local::lib, Carton) work unmodified.

  • Host library trees are probed, not baked. @INC is constructed by checking the standard Arch, Debian and Fedora pure-perl tree locations for existence, and versioned children of those trees and of -I/PERL5LIB entries are ordered by nearness to pperl’s own version: exact match first, then the same minor release descending, then newer versions, then the plain directory, then older versions. A host perl of a different version is used gracefully as a last resort rather than rejected. pperl -V always shows the actual probed result.

Additionally, pperl-private search locations exist for parallel installations: the PPERL5LIB environment variable (honored before PERL5LIB, same rules) and the overlay trees under /usr/local/share/pperl and /usr/share/pperl, probed before every host tree. They allow shipping or overriding a .pm for pperl without touching the shared perl trees; the host perl never reads them, and nothing in them can outrank a built-in native module.

No interpreter threads#

use threads is not supported (pperl is a non-threaded build, as are most distribution perls’ recommended configurations). Perl-level concurrency options are fork and the automatic parallelization of qualifying loops, which uses native threads internally without exposing interpreter threading semantics.

Linux only#

PetaPerl runs on Linux exclusively (any architecture supported by Cranelift: x86-64, AArch64, RISC-V, s390x). $^O is always "linux".

Version identity#

$] reports 5.044099 and $^V reports v5.44.99: a 5.44-class interpreter, above any released 5.44.x patch level. use v5.44 and version checks against 5.44 or below behave exactly as on a real 5.44. $Config{version} reports 5.44.0.

Modern features are NOT enabled by default: exactly like perl, say, state or signatures need use feature ... or a use v5.XX declaration. Scripts written for older perls run with their old semantics.

Command-line flags#

Not supported:

Flag

Description

-M / -m

Load module from command line

-x

Extract script from message

-d

Interactive debugger

-I, -n/-p, -l, -a/-F, -0, -i, -T/-t, -c, -w, -e/-E and -V/-V:key work as in perl. pperl-specific flags (JIT, parallelism) are listed in CLI options.

Known Issues#

Current, specific, and expected to shrink:

  • charnames emits redefinition warnings. Loading charnames (or \N{...} names) prints Subroutine re::is_regexp redefined warnings before working correctly: the built-in re module pre-registers helpers that _charnames.pm also defines. Output is otherwise exact.

  • B::Deparse on subs with signatures. The optree for signature parameters uses a newer internal representation than the deparser expects; deparsing such subs produces an “unexpected OP” note instead of the signature. Ordinary subs deparse exactly.

  • Embedding pperl in C hosts (mod_perl-class, programs linking libperl) is out of scope until a concrete user appears.