Read perlintern Safely Before Touching Perl's Private API
You will finish with a reliable way to inspect perlintern(1), tell private interpreter internals from the supported Perl API, and decide when an internal function should be replaced rather than copied into an extension. On this Ubuntu system the installed manual comes from Perl 5.38.2, package perl-doc version 5.38.2-3.2ubuntu0.6.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell and the perl-doc package. No compiler, root privileges or running service is required. The commands below only read documentation and package metadata.
1. Confirm what is installed
perlintern is a manual page, not a command you execute. Start by checking the package and the manual path:
$ dpkg-query -W -f='${Package} ${Version}\n' perl-doc
perl-doc 5.38.2-3.2ubuntu0.6
$ man -w perlintern
/usr/share/man/man1/perlintern.1.gz
The first line identifies the documentation package and version. The second shows that the local copy is compressed under /usr/share/man/man1. If man -w reports that the page cannot be found, install or repair perl-doc using your normal package-management process. That is an administrative change, so it is not included as an automatic step here.
Checkpoint: command -v perlintern should print nothing. That is expected. Do not treat the missing executable as a failed Perl installation.
2. Read the warning before reading the names
Open the page in the ordinary way:
$ man 1 perlintern
The page is autogenerated documentation for functions documented inside the Perl interpreter but not marked as part of the Perl API. Its central boundary is simple: these functions are not for use in extensions. The long list of names is not a list of stable libraries or shell commands. It is an implementation map for people working on Perl itself.
That distinction matters when you find a name that appears to solve a problem. An entry such as av_fetch_simple exposes a C signature and a rough Perl equivalent, but it also relies on assumptions about the array: no magic, not read-only, real storage, and a non-negative key. Violating those assumptions can make an extension corrupt data or fail in a way that only appears with a different Perl build.
Do not copy an internal signature into a project merely because it is documented. Treat each entry as evidence about the interpreter, not as an interface contract.
3. Search the page for a suspected helper
For a quick, non-interactive search, send the rendered manual through col and grep:
$ man 1 perlintern | col -b | grep -n -A8 -B2 'av_fetch_simple'
...
The exact line numbers and surrounding text depend on the installed Perl release. The useful result is the entry's description, its assumptions, and any warning about experimental or deprecated status. Use grep -n -A8 -B2 as a starting window, then widen it if the entry continues beyond the displayed context.
You can also inspect the compressed source directly when you need to preserve formatting for a review:
$ zcat /usr/share/man/man1/perlintern.1.gz | sed -n '/^\.SH "AV Handling"/,/^\.SH /p' | head -80
This shows the roff source, not a separate API. Prefer man for reading and use zcat only when you are debugging the packaged documentation itself.
Checkpoint: record the page version and the full warning attached to the entry. A function name without its preconditions is not enough information for a safe change.
4. Check the public API before writing C
The matching public reference is perlapi(1). Search it for the same concept, then read the surrounding section:
$ man 1 perlapi | col -b | grep -n -A12 -B3 'av_fetch'
$ man 1 perlguts | col -b | grep -n -A12 -B3 'array'
A public entry does not remove the need to understand reference counts, magic, thread context or the lifetime of an SV. It does give you the supported starting point for an XS module or embedded interpreter. perlguts supplies the concepts; perlapi supplies the public names and signatures; perlintern explains private implementation details that may help you understand a failure.
When both pages describe a capability, prefer the public API. In the local perlintern page, av_new_alloc is described as implementing public allocation helpers. That is a signal to use the public helpers in new code, not an invitation to call the internal implementation directly.
5. Treat experimental and deprecated entries as stop signs
Some entries are explicitly experimental and may change or disappear without notice. Others are deprecated undocumented elements, with a direct instruction not to use them in new code. A third category is an implementation helper that the page says should not be called directly, such as a function invoked through Perl's magic machinery.
Use a short review record when an existing extension mentions one:
Perl version checked: 5.38.2
Internal symbol: <PRIVATE_SYMBOL>
Why it was found: <source file and line>
Public replacement checked: <perlapi entry or none>
Decision: replace, isolate, or keep only for a pinned Perl build
Replace the angle-bracket placeholders before saving the record. If no public replacement exists, isolate the dependency behind a small compatibility layer, pin and test the Perl versions you support, and document that the code depends on an unstable interpreter detail. That is a maintenance decision, not a guarantee of compatibility.
6. Recheck after a Perl upgrade
The page is generated from the Perl source for the installed release. Names, sections, warnings and signatures can therefore change when Perl changes. Capture the local version and compare the relevant entries after an upgrade:
$ perl -e 'print "$^V\n"'
v5.38.2
$ man -w perlintern
/usr/share/man/man1/perlintern.1.gz
$ zcat /usr/share/man/man1/perlintern.1.gz | grep -n 'DEPRECATED\|experimental' | head
The final command is only a quick inventory. Read each matching section before deciding that an old workaround is still valid. Do not assume that a symbol surviving in the manual remains callable, exported or semantically identical in a later release.
There is nothing to undo from this guide: all examples are read-only. If you started from a failing extension build, restore changes through that project's normal version-control workflow rather than deleting files or changing system Perl.
Done means
- You confirmed that
perlinternis a manual page supplied by the installedperl-docpackage. - You recorded the Perl version and the private entry's assumptions or warnings.
- You checked
perlapiandperlgutsbefore considering C or XS code. - You will treat experimental, deprecated and implementation-only symbols as compatibility risks.
- You have a version-check step to repeat after upgrading Perl.