This week in PSC (223) | 2026-05-04
All three of us attended for some more issue triage. We accepted some assorted small fixes and CPAN dual-life module updates. The release blocker list remains empty.
All three of us attended for some more issue triage. We accepted some assorted small fixes and CPAN dual-life module updates. The release blocker list remains empty.
Use AI. Use it more and better. If you are not yet equipped to use it well - that is fine, learning takes time - but please do not inhibit those in the community who are.
That is the whole argument. The rest of this piece is why I think it is correct, and why I think the current register of the Perl community around this topic is costing us something specific and avoidable.
This is a developer's perspective, not legal advice. I'm not a lawyer. What follows is my personal reading of publicly available licenses, policy documents, and one court decision. If you're making decisions about your module's legal exposure, talk to a lawyer.
The open source world is actively debating whether to accept AI-assisted contributions. QEMU, NetBSD, and Gentoo have said no. A lot of CPAN maintainers haven't written down a policy but have a reflex — if a PR looks AI-assisted, close it without a real review.
Two very different concerns sit underneath that reflex, and they usually get mashed together:
I found this sufficient of an obstacle that I wanted to post about it for future posterity.
I was able to cpanm Google::ProtocolBuffers::Dynamic after installing these packages on Debian Trixie.
The last library eluded me and caused the most frustration. Anyway on to other things.
This meeting took place at the Perl Toolchain Summit 2026. All three of us met in person in Vienna and reviewed our release blocker status. Things are in the clear: no new blockers have come in since last meeting, and the previously identified ones are already resolved, with a single exception, namely the workflow for EOL notices in release announcements. Conveniently, Philippe, who just released 5.43.10, is also in attendance in Vienna, and has provided concrete feedback, so this is being addressed.

Two weeks ago we posted "PDL in Rust - A Native Reimplementation of the Perl Data Language". At the time the score was 45 tests, all green. That was enough to say "it compiles, it runs, here is the arithmetic surface." It was not enough to say "you can use this."
We are now on the second number. The current PDL implementation in pperl covers roughly 3,000 assertions end-to-end: about 1,400 on the Perl-facing connector side and about 1,600 on the engine side. As of this writing roughly 98% of the connector assertions match upstream PDL 2.103 exactly, and most of the remaining couple of dozen we already know why they fail. By the time you read this the numbers will have drifted a little in our favour - give or take - but the shape is the point, not the decimal.
Everything described below is shipping, today, at https://perl.petamem.com.
A while back, I received a pull request suggesting that I update the performance comparison with Encode.pm in my module, Unicode::UTF8. When I originally wrote Unicode::UTF8, Encode.pm used its own UTF-8 validation implementation. Since then, Karl Williamson has done extensive work improving Perl, and Encode.pm now relies on those validation routines based on Björn Höhrmann’s UTF-8 DFA decoder. It’s an elegant piece of code, widely adopted across many projects.
That said, I wasn’t particularly motivated to revisit the comparison, so I decided instead to look into faster scalar C implementations. While it has been suggested that Unicode::UTF8 should gain a SIMD implementation, and that may well be worthwhile, I wanted to first explore improvements to the scalar path, which would still be required as a fallback.
After some searching, I came across a tweet by Russ Cox showing performance numbers for a shift-based DFA implementation in Go, along with a link to a gist by Per Vognsen describing the technique.
So you've got a bunch of Perl worker processes and they need to share state. A work queue, a counter, a lookup table - the usual. What do you reach for?
Perl has solid options here, and they've been around for a while. File::Map gives you clean zero-copy access to mmap'd files - substr, index, even regexes run directly on mapped memory. LMDB_File wraps the Lightning Memory-Mapped Database - mature, ACID-compliant, lock-free concurrent readers via MVCC, crash-safe persistence. Hash::SharedMem offers a purpose-built concurrent hash with lock-free reads and atomic copy-on-write updates. Cache::FastMmap is the workhorse for shared caching - mmap-backed pages with per-page fcntl locking, LRU eviction, and optional compression.
All three of us attended this long meeting consisting entirely of dealing with release blockers.
Dependencies or prerequisites are an integral feature of the CPAN software repository. They define what other CPAN modules are required for a particular CPAN distribution to be built, tested, or ultimately to function, as well as optionally to improve or add functionality. To define them properly for a distribution, it is helpful to understand exactly how they will be used, and what all the different distribution files like Makefile.PL, Build.PL, META.json, and MYMETA.json are for.
sidebar: In this post, I will focus on the "requires" relationship for dependencies, which are hard dependencies that must be satisfied, but "recommends" and "suggests" relationships are also defined that indicate strongly and weakly optional dependencies respectively; CPAN installers may install these based on the options that are passed.
Most commonly and at a basic level, dependencies are defined in a (generated) file called META.json in the root of the CPAN distribution, but this may not be the complete picture. CPAN installers historically would determine what is needed at the time that the user requests to install the distribution ("install time"), and though there is now the formal concept of static prerequisites (the most common case where they are the same for every install environment), some distributions need to determine prerequisites at install time, using the original dynamic configuration process.
I wrote a follow up of my previous article on dev-to. It is titled Manage the health of your CLI tools at scale and explores how you might approach instrumenting your cli tools to ensure they run properly.
tl;dr
Choose a bug that has a reproducing case from the list of open issues. Get the Perl source from GitHub, and put the reproducing case into a test file that we have designed for the purpose, and submit a pull request to GitHub for it. That's it.
The test is marked as expected to fail. Having this test in place helps us in several ways. One is that sometimes having to write a test is the straw that leads a developer to think it's just too much trouble to tackle this. Another is that, not all that infrequently, a change made for some other reason fixes one of these bugs, and we don't know it. But having this test would cause us to get notified that the bug is now fixed. It might even be that your work would show that the bug is already fixed.
Sometimes, when you're trying to debug encoding issues in Perl code, it is useful to quickly get an idea of what code points Perl thinks are in your string. The straightforward approach of say $string (or print $string) isn't a good way to look at an unknown string: The results depend on what encoding layers (if any) are set on STDOUT and how your terminal renders the resulting bytes. In some cases, "\xe2\x82\xac" (a three-character string, UTF-8 bytes) may look identical to "\x{20ac}" (a one-character string, Unicode text) when printed, for example. (And some control characters are invisible or can clear (parts of) the screen or reposition the cursor, etc.)
Data::Dumper isn't great, either: For one thing, you have to load it first and second, a naive use Data::Dumper; print Dumper($string) can still dump non-printable control characters on your terminal. You have to remember to set $Data::Dumper::Useqq = 1 first, which is a hassle (and takes another line of code).
I am preparing a new version of SQL::Abstract::More, aimed principally at solving several long-standing bugs when param ‘quote_char’ is non-empty (i.e when the user wants to generate SQL of shape like "SELECT `Foo`.`col1`, … FROM `Foo` etc.").
While working on this I need some input from users, because the situation is a bit complicated:
On March 17th, I installed a bot called koan on my personal Claude account. It's designed to monitor your four-hour usage limits, maintain a queue of "missions," and efficiently use your credits — even while you're sleeping.
Three weeks later, I had reviewed and merged 575 pull requests across 20 CPAN repositories, cut 58 releases across 17 of them, and caught memory leaks, security holes, and long-standing bugs that nobody had gotten around to fixing in years.
Some people think that means I let an AI commit unchecked code to critical Perl infrastructure. I want to explain what actually happened.
Here's what those three weeks produced:
| Repository | PRs Merged | Releases |
|---|---|---|
| XML-Parser | 95 | 8 |
| IPC-Run | 68 | 3 |
| YAML-Syck | 64 | 7 |
| Net-Jabber-Bot | 38 | 3 |
| Net-ACME2 | 38 | 1 |
| Net-Ident | 33 | 5 |
| Crypt-RIPEMD160 | 33 | 4 |
| IO-Stty | 30 | 4 |
| Razor2-Client-Agent | 27 | 2 |
| Tree-MultiNode | 24 | 2 |
| IO-Tty | 22 | 7 |
| Business-UPS | 20 | 2 |
| Test-MockFile | 17 | 2 |
| Safe-Hole | 17 | 3 |
| Tie-DBI | 15 | 1 |
| Regexp-Parser | 11 | 3 |
| Sys-Mmap | 9 | 1 |
| Template2 | 6 | — |
| Crypt-OpenSSL-RSA | 4 | — |
| CDB_File | 4 | — |
| Total | 575 | 58 |
We were all present.

A few days ago, when we announced pperl's native module strategy on Reddit, someone asked about PDL support. We replied: "PDL will be supported." — to which u/fuzzmonkey35 responded: "We will live in glorious times when this happens."
Well. It happened.
We (as in: we and our AIs) reimplemented PDL (the Perl Data Language) from scratch in Rust — not a binding, not an FFI wrapper, but a ground-up reimplementation of the core engine. 15 data types, N-dimensional arrays, broadcasting, operator overloading, reductions, linear algebra, transcendental math — all in pure Rust, integrated as a native module into our pperl next-gen Perl5 platform.
use PDL; my $a = pdl([1, 2, 3]); my $b = pdl([10, 20, 30]); say $a + $b; # [11 22 33] say ($a * $b)->sum; # 140 say sin(pdl([0, 3.14159/2, 3.14159]));
45 tests, all green. Same Perl syntax. No XS. No C. No libpdl.
Modern software distribution has converged on a simple idea: ship a self-contained artifact. Whether that means a statically linked binary, a container image, or a snap/flatpak, the benefits are the same -- dependency management is solved at build time, platform differences are absorbed, and upgrades and rollbacks reduce to swapping a single file.
Perl's App::FatPacker
applies the same principle to Perl scripts. It bundles every pure-Perl
dependency into a single executable file. No cpanm, no
local::lib, no Makefile on the target -- just copy the file
and run it. The technique is well-established -- cpm (the
CPAN installer we use in the build) is itself distributed as a fatpacked
binary.
The distribution pipeline looks like this:
Code repo --> CI --> fatpack --> deploy --> laptops / jumpboxes / servers
|
single file,
no dependencies
Continuing the dev.to series about beautiful Perl features, here are the recent articles (March 2026) :
All three of us attended.
We discussed policy questions that were turned up by the recent submission of some LLM-generated PRs. We need to hold conversation about this among the Core team. No contributions of this kind will be accepted while the discussion is still ongoing.
We finally had a good chunk of time to spend on release blocker triage. We made quick progress, working through half our list and closing some issues in the process. We newly marked 4 issues as blockers.
blogs.perl.org is a common blogging platform for the Perl community. Written in Perl with a graphic design donated by Six Apart, Ltd.