Shortcuts: s show h hide n next p prev
PerlIOScalar_write: further avoid SvCUR() on undefined scalar

This is a supplement to my previous commit
10479682983ec87385921d8e144f2edb1676fc9f.  There were still cases
where SvCUR() was called for an undefined SV, which used cause
the newly created scalar not to be truncated or padded properly.

t/io/scalar.t: added tests for this change.

Evolution of DBIx::Class::Async

blogs.perl.org


How do you make the world’s best Perl ORM non-blocking without rewriting your entire schema? Find out the answer in this post: https://theweeklychallenge.org/blog/dbix-class-async-evolution

B/Concise.pm: Bump version to 1.011

Perl commits on GitHub
B/Concise.pm: Bump version to 1.011

“Perl is my cast-iron pan - reliable, versatile, durable, and continues to be ever so useful.” TPRC 2026 brings together a community that embodies all of these qualities, and we’re looking for sponsors to help make this special gathering possible.

About the Conference

The Perl and Raku Conference 2026 is a community-organized gathering of developers, enthusiasts, and industry professionals. It takes place from June 26-28, 2026, in Greenville, South Carolina. The conference will feature an intimate, single-track format that promises high sponsor visibility. We look forward to approximately 80 participants with some of those staying in town for the shoulder days (June 25-29) and a Monday workshop.

Why Sponsor?

  • Give back to the language and communities which have already given so much to you
  • Connect with the developers and craftspeople who build your tools – the ones that are built to last
  • Help to ensure that The Perl and Raku Foundation can continue to fund Perl 5 core maintenance and Community Grants

Sponsorship Tiers

Platinum Sponsor ($6,000)

  • Only 1 sponsorship is available at this level
  • Premium logo placement on conference website
  • This donation qualifies your organization to be a Bronze Level Sponsor of The Perl and Raku Foundation
  • 5-minute speaking slot during opening ceremony
  • 2 complimentary conference passes
  • Priority choice of rollup banner placement
  • Logo prominently displayed on conference badges
  • First choice of major named sponsorship (Conference Dinner, T-shirts, or Swag Bags)
  • Logo on main stage backdrop and conference banners
  • Social media promotion
  • All benefits of lower tiers

Gold Sponsor ($4,000)

  • Logo on all conference materials
  • One complimentary conference pass
  • Rollup banner on display
  • Choice of named sponsorship (Lunch or Snacks)
  • Logo on backdrop and banners
  • Dedicated social media recognition
  • All benefits of lower tiers

Silver Sponsor ($2,000)

  • Logo on conference website
  • Logo on backdrop and banners
  • Choice of smaller named sponsorship (Beverage Bars)
  • Social media mention
  • All benefits of lower tier

Bronze Sponsor ($1,000)

  • Name/logo on conference website
  • Name/logo on backdrop and banners

All Sponsors Receive

  • Logo/name in Update::Daily conference newsletter sidebar
  • Opportunity to provide materials for conference swag bags
  • Recognition during opening and closing ceremonies
  • Listed on conference website sponsor page
  • Mentioned in conference social media

Named Sponsorship Opportunities

Exclusive naming rights available for:

  • Conference Dinner ($2,000) - Signage on tables and buffet
  • Conference Swag Bags ($1,500) - Logo on bags
  • Conference T-Shirts ($1,500) - Logo on sleeve
  • Lunches ($1,500) - Signage at pickup and on menu tickets
  • Snacks ($1,000) - Signage at snack bar
  • Update::Daily Printing ($200) - Logo on masthead

About The Perl and Raku Foundation

Proceeds beyond conference expenses support The Perl and Raku Foundation, a non-profit organization dedicated to advancing the Perl and Raku programming languages through open source development, education, and community building.

Contact Information

For more information on how to become a sponsor, please contact: olaf@perlfoundation.org

Modernise B::Concise a little

Perl commits on GitHub
Modernise B::Concise a little

 - Move the version declaration into the package line.
 - Use v5.40 to get strict, warnings, and the module_true feature.
 - Make use of the isa and //= operators.
 - Use a for loop to iterate over multiple values at a time.
 - Remove indirect object notation from the test.
embed.pl: RXf_PMf_ symbols should be visible everywhere

Fixes #24153; Fixes #24154

The spelling of various symbols changed in 5.43, to align with the C
Standard.  That meant that any code using the old symbol, and which
didn't get updated, would break.  Macros that used the old symbol were
updated to use the new one.  Since we didn't get breakage, that meant
there was no tested code that used the old spelling directly.

When I was backporting the hardening of visibility to the beginning of
5.43, I found the spelling changes.  If I didn't find a macro that used
the new spelling, I concluded that this symbol wasn't used in CPAN, even
indirectly.  (I grepped a snapshot of metacpan to rule out direct
mentions.)

For the symbols that broke here, I did find indirect uses, but it
appeared to me that these were only uses by Perl extensions.  I was
clearly wrong.

This fact indicates that we can resolve these symbols; they are needed
to be visible everywhere.  There's three ways to resolve such things:

1.  Document them.  I don't see any real need for code beyond the already
    existing code from needing to use them.  Their use is obvious once
    you see the pattern, so I  don't see a need for them to even be put
    in perlintern.
2.  Change their names to begin with Perl_.  This might be something to
    do at a later date, but not in the 5.43 cycle.
3.  Put them on the resolved list.  I've opted for that now.

embed.pl: Reorder a list; add comments

Perl commits on GitHub
embed.pl: Reorder a list; add comments

Naming a symbol with a trailing underscore indicates an intent for that
symbol to not be used directly by XS code.  Separating those from the
other symbols highlights this.

Golf coding challenge

r/perl

In a Translation Memory (TM) system, duplicate entries can accumulate over time.

Your task is to count how many entries are redundant and identify the busiest day, and encode which entries are duplicates using a binary bitmask.

Given a list of translation memory entries in the format: "source#target#date", count the total number of duplicate entries and find the date with the most entries, and create a bitmask where each bit represents whether an entry is a duplicate (1 = duplicate, 0 = unique).

An entry is considered a duplicate if the same source-target pair (or its reverse) has already been seen.

Note:

- Reverse pairs (e.g., "Hello#Hola" and "Hola#Hello") are treated as the same pair.

- Entries are case-insensitive (e.g., "Hello#Hola" and "hello#hola" are the same).

- The input will be provided via command-line arguments.

- Output Format: duplicates_count#most_active_date#bitmask_decimal Where bitmask_decimal is the binary representation (1 = duplicate, 0 = unique) converted to decimal. Read bits from right to left (LSb = least significant bit).Example:Input:

Hello#Hola#2024-01-01

Hi#Bye#2024-01-01

Hello#Hola#2024-01-02

Hola#Hello#2024-01-03

Hi#Bye#2024-01-03

Good#Bom#2024-01-03

Expected Output:

3#2024-01-03#28

Explanation:

Entry 1: "Hello#Hola" → First occurrence, NOT a duplicate (bit: 0)

Entry 2: "Hi#Bye" → First occurrence, NOT a duplicate (bit: 0)

Entry 3: "Hello#Hola" → Duplicate of Entry 1 (bit: 1, count: 1)

Entry 4: "Hola#Hello" → Reverse of Entry 1, IS a duplicate (bit: 1, count: 2)

Entry 5: "Hi#Bye" → Duplicate of Entry 2 (bit: 1, count: 3)

Entry 6: "Good#Bom" → First occurrence, NOT a duplicate (bit: 0)

Date Frequency:

2024-01-01: 2 entries

2024-01-02: 1 entry

2024-01-03: 3 entries ← Most active date

Bitmask Construction (reading right to left):

Position: 5 4 3 2 1 0

Bitmask: 0 1 1 1 0 0

Binary: 011100

Decimal: 28

Output: 3#2024-01-03#28

We need to complete this with lowest bytes.

Current lowest is 90 bytes with perl 5.28.1

How is it possible?

Can we try for 90-94

Anyone knows tricks

My 99 byte solution

map{($d,@k)=sort split/#/,uc;$m=$d if$v{$m}<++$v{$d};$b+=!!$u{"@k"}++<<$i++}@ARGV;print$i-keys%u,"#$m#$b"

submitted by /u/Akshay_NewRich
[link] [comments]

Weekly Challenge: Digital reduction

dev.to #perl

Weekly Challenge 359

Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.

Challenge, My solutions

Task 1: Digital Root

Task

You are given a positive integer, $int.

Write a function that calculates the additive persistence of a positive integer and also return the digital root.

  • Digital root is the recursive sum of all digits in a number until a single digit is obtained.
  • Additive persistence is the number of times you need to sum the digits to reach a single digit.

My solution

Starting this week, I'm going to turn off VS Code Copilot when completing the challenge. As AI takes over the task of code completion, it's still a good exercise to do things by hand so as I don't depend on it.

For this tasks, I create two variables. The first is called persistence and starts at 0. The second variable is called digital_root and starts with the supplied integer. This is called number in Python, as int is a reserved word.

I then have a loop that continues until digital_root is a single digit. Breaking down the line:

  • str(digital_root) will convert the digital_root integer to a string
  • d for d in will convert each character to a single digit
  • map(int(... will convert the digit back to an integer
  • sum(... will add the single digit

I also increment the persistence value by one. I end by returning the two values. The main function is responsible for displaying the text as per the examples.

def get_digital_root(number: int) -> tuple[int, int]:
    if number <= 0:
        raise ValueError("You must provide a positive integer")

    persistence = 0
    digital_root = number

    while len(str(digital_root)) > 1:
        digital_root = sum(map(int, (d for d in str(digital_root))))
        persistence += 1

    return persistence, digital_root

The Perl solution follows the same logic. Perl doesn't make a distinction between string and integers (yes, there are some exceptions to this rule), but does require the split function to break the digital_root value into individual digits.

use List::Util 'sum';

sub main ($int) {
    my $persistence  = 0;
    my $digital_root = $int;

    # Keep iterating until we have a single digital
    while ( length($digital_root) > 1 ) {
        $digital_root = sum( split( //, $digital_root ) );
        $persistence++;
    }

    say "Persistence  = $persistence";
    say "Digital Root = $digital_root";

Examples

$ ./ch-1.py 38
Persistence  = 2
Digital Root = 2

$ ./ch-1.py 7
Persistence  = 0
Digital Root = 7

$ ./ch-1.py 999
Persistence  = 2
Digital Root = 9

$ ./ch-1.py 1999999999
Persistence  = 3
Digital Root = 1

$ ./ch-1.py 101010
Persistence  = 1
Digital Root = 3

Task 2: String Reduction

Task

You are given a word containing only alphabets.

Write a function that repeatedly removes adjacent duplicate characters from a string until no adjacent duplicates remain and return the final word.

My solution

This is a duplicate (albeit slightly re-worded) of the first task in week 340. Therefore I copy and pasted that code, and renamed the function. See my original blog post on how this was solved.

Examples

$ ./ch-2.py aabbccdd
""

$ ./ch-2.py abccba
""

$ ./ch-2.py abcdef
"abcdef"

$ ./ch-2.py aabbaeaccdd
"aea"

$ ./ch-2.py mississippi
"m"

Perl 🐪 Weekly #758 - PTS 2026

dev.to #perl

Originally published at Perl Weekly 758

Hi there,

The upcoming Perl Toolchain Summit (PTS) in Vienna is more than just a conference, it's an important event at which to maintain, discuss, and improve on the CPAN toolchain, which is the fundamental foundation of the Perl ecosystem. Through their commitment to volunteerism, the volunteers who attend this gathering can provide significant amounts of personal time and expertise towards supporting the efforts of others in the Perl community, benefiting every single person and company that utilises Perl.

A recent article by Philippe Bruhat reports on the true cost associated with collaborating to support the PTS. The article provides a new paradigm for companies wanting to provide sponsorship for their employees who will be attending on paid time: consider "paying it forward". Estimate the cost of your employee's participation and provide that amount to the PTS in the form of a monetary sponsorship. By doing this simple action of doubling your company's investment, your company will directly provide the funding for another deserving attendee of the PTS to benefit as well, thus increasing the overall impact of the PTS.

This proposed model transforms how a company supports the employee(s) attending, creating a ripple effect through the Perl community by providing additional funding to support a more diverse, larger pool of contributors, which will serve to support the continued viability and innovation of the tools that are relied upon by everyone within the community, regardless of whether or not they attend the PTS.

This isn't simply charity, it's a wise business strategy for investing in the foundation of the Perl community. Through "pay it forward" sponsorship opportunities, companies have access to those developing the guidelines for developing and supporting the future of Perl. This creates visibility for them as true community supporters while helping the PTS remain the innovative, viable engine that brings Perl into a current competitive position. Let's continue to support all those that also support us.

Last year, I was lucky enough to attend the event as I received a surprise invitation by the organisers. From this experience, I can say it was the best of all Perl events I have been to. Contributing in any small way was a great feeling and made it worthwhile. One of the highlights was observing how committed all the top individuals in the Perl community were. They worked together on multiple projects simultaneously, with maximum efficiency, to achieve all that they could during the event.

Keep your spirits up and stay healthy. Enjoy rest of the newsletter.

--
Your editor: Mohammad Sajid Anwar.

Announcements

Sydney February Meeting! 2025

Sydney Perl continues regular meetings with our next in February

This week in PSC (213) | 2026-01-26

Perl Steering Council, discussing topics like improvements to Perl's random number generator and integrating TLS functionality into the core.

A new sponsorship model

A new sponsorship model for the 2026 Perl Toolchain Summit. It encourages employers sending staff to the event to "pay it forward" by also providing monetary sponsorship to help cover costs for other attendees.

ANNOUNCE: Perl.Wiki V 1.39 & Mojolicious.Wiki V 1.13

Articles

What I learned from being an editor/reviewer for the 2025 Perl Advent Calendar

Marc contemplates on having a wonderful experience reviewing for the Perl Advent Calendar 2025. He noted that through writing and editing articles about other peoples' articles and writing with CPAN, he learned about many new things (CPAN modules) as well as found renewed interest in various community activities such as The Weekly Perl Challenge.

Lock and unlock hash using Hash::Util

The post demonstrates how to use the Hash::Util module's lock_hash function in Perl to prevent accidental modifications to a hash, protecting it from changes, deletions, or new key additions. By unlocking the hash with unlock_hash, the program regains the ability to modify its structure, which is shown with practical code examples.

Podlite comes to Perl: a lightweight block-based markup language for everyday use

The article introduces Podlite, a new lightweight, block-based markup language that brings the readability and structure of Raku's documentation format (Pod) to the Perl ecosystem. It highlights how Podlite offers three interchangeable block styles for writing documentation within Perl code and announces its arrival via a CPAN module, positioning it as a modern tool for everyday use.

The Weekly Challenge

The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. You can even win prize money of $50 by participating in the weekly challenge. We pick one champion at the end of the month from among all of the contributors during the month, thanks to the sponsor Lance Wicks.

The Weekly Challenge - 359

Welcome to a new week with a couple of fun tasks "Digital Root" and "String Reduction". If you are new to the weekly challenge then why not join us and have fun every week. For more information, please read the FAQ.

RECAP - The Weekly Challenge - 358

Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Max Str Value" and "Encrypted String" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.

/Stringed Max

In addition to providing an intuitive method of handling both numeric and non-numeric strings, this solution illustrates Raku's syntax for implementing pattern matching and type-converting through the use of cleanly written code.

Perl Weekly Challenge: Week 358

Jaldhar is using both Raku and Perl versions in order to demonstrate an accurate solution and make the language-specific optimizations (e.g., using map and the modulo operator) obvious by showing how he was able to arrive at a practical solution in one line of code.

Maximum Encryption

An in-depth study of technical solutions where unique implementations are provided for both Perl as well as J. Jorg used sophisticated methods, such as the String::Compile::Tr module, to translate from one programming language to another at runtime and explores more unusual 'under' conjunctions in J.

using brute force!

Explicitly calling methods such as "brute force", Luca particularly favours a try-catch approach (as in Java and Python) for converting strings into integers. This method is an interesting and practical alternative to the regular expression check that most people use.

Perl Weekly Challenge 358

This blog post offers a concise and efficient one-liner approach to both tasks of Weekly Challenge 358, with a particular focus on Perl's command-line capabilities.

nbyqyyefswbuffyhay

Matthias Muth's solutions are exemplary for their elegant use of Perl's functional features and their practical robustness. They achieve maximum effect with minimal code, a hallmark of expert Perl programming.

It’s What You Value

This solution from Packy is both distinctive and highly educational. It provides a fantastic comparative study across four languages (Raku, Perl, Python, and Elixir), showcasing how to solve the same problems with each language's unique idioms and strengths. The author's thoughtful explanations make it a great learning resource.

A number of strings

This approach places emphasis on clarity, detail, and practical (real-life) use of the code to solve the problem at hand as opposed to using clever short phrases (i.e., making it well-engineered). An example of properly designed, production focused,

The Weekly Challenge #358

Robbie Hatley's Perl provided an easy to follow solution which employed procedural programming techniques for the two tasks. The approach is reasonable and aligns closely with the specifications given in the problem statement.

Encrypted Max

The practical programming method and mathematically careful design are what makes this solution stand out. It puts its emphasis on correctness and safety and places particular emphasis on how the modulo function and character encodings are handled; therefore, it is a well-thought-out and robust implementation.

Maximum Encryption

Simon Green's solutions stand out for their practical efficiency, clear idiomatic code, and a smart pre-computation strategy that differentiates them from the more common inline calculation methods.

When Strings Become Numbers and Letters Start Shifting

The main factor separating this solution from others is its pedagogical quality, not the code itself. The explanation of how the algorithms (digit validation, ASCII rotation) work is clear, and demonstrates Perl's suitability for these types of tasks. Additionally, this solution emphasizes the importance of writing testable code, which provides valuable insight.

Rakudo

2026.04 Hello, Goodbye

Weekly collections

NICEPERL's lists

Great CPAN modules released last week.

The corner of Gabor

A couple of entries sneaked in by Gabor.

Add META data, .gitignore and GitHub Actions to Common::CodingTools

This is the video recording from December 2025. It includes some explanation on how to find a Perl module to contribute to and we also make some small contributions. For similar events check out the OSDC Perl page.

Perl-related GitHub organizations

There are now some 40 organization listed, thanks in no small part to the people in the Perl community who suggested them.

WhatsApp

Join the Perl Maven chat group on WhatsApp!

Telegram

Join the Perl Maven chat group on Telegram!

Events

Perl Maven online: Code-reading and Open Source contribution

February 10, 2025

Boston.pm - online

February 10, 2025

Paris.pm monthly meeting

February 11, 2025

Paris.pm monthly meeting

March 11, 2025

German Perl/Raku Workshop 2026 in Berlin

March 16-18, 2025

You joined the Perl Weekly to get weekly e-mails about the Perl programming language and related topics.

Want to see more? See the archives of all the issues.

Not yet subscribed to the newsletter? Join us free of charge!

(C) Copyright Gabor Szabo
The articles are copyright the respective authors.

Welcome to the Week #359 of The Weekly Challenge.
Thank you Team PWC for your continuous support and encouragement.
Thank you Team PWC for your continuous support and encouragement.

OSDC Perl.

  • 00:00 Introduction to OSDC
  • 01:30 Introducing myself Perl Maven, Perl Weekly
  • 02:10 The earlier issues.
  • 03:10 How to select a project to contribute to?
  • 04:50 Chat on OSDC Zulip
  • 06:45 How to select a Perl project?
  • 09:20 CPAN::Digger
  • 10:10 Modules that don't have a link to their VCS.
  • 13:00 Missing CI - GitHub Actions or GitLab Pipeline and Travis-CI.
  • 14:00 Look at Term-ANSIEncode by Richard Kelsch - How to find the repository of this project?
  • 15:38 Switching top look at Common-CodingTools by mistake.
  • 16:30 How MetaCPAN knows where is the repository?
  • 17:52 Clone the repository.
  • 18:15 Use the szabgab/perl Docker container.
  • 22:10 Run perl Makefile.PL, install dependency, run make and make distdir.
  • 23:40 See the generated META.json file.
  • 24:05 Edit the Makefile.PL
  • 24:55 Explaining my method of cloning first (calling it origin) and forking later and calling that fork.
  • 27:00 Really edit Makefile.PL and add the META_MERGE section and verify the generated META.json file.
  • 29:00 Create a branch locally. Commit the change.
  • 30:10 Create a fork on GitHub.
  • 31:45 Add the fork as a remote repository and push the branch to it.
  • 33:20 Linking to the PR on the OSDC Perl report page.
  • 35:00 Planning to add .gitignore and maybe setting up GitHub Action.
  • 36:00 Start from the main branch, create the .gitignore file.
  • 39:00 Run the tests locally. Set up GitHub Actions to run the tests on every push.
  • 44:00 Editing the GHA configuration file.
  • 48:30 Commit, push to the fork, check the results of GitHub Action in my fork on GitHub.
  • 51:45 Look at the version of the perldocker/perl-tester Docker image.
  • 54:40 Update list of Perl versions in the CI. See the results on GitHub.
  • 55:30 Show the version number of perl.

One of the things I enjoy about the Weekly Perl Challenge (WPC) is how small problems often hide neat programming ideas.
This week, I solved two challenges that look simple at first glance but beautifully showcase Perl’s strengths in:

  • String handling
  • Regex usage
  • Numeric/string duality
  • ASCII manipulation
  • Writing clean, testable code

Let’s walk through both problems and the approach I used.

Challenge 1 — When Strings Become Numbers

Problem
You are given a list of strings. For each string:

  • If it contains only digits, treat it as a number
  • Otherwise, treat its length as its value From these values, return the maximum.

Example

Strings Interpreted as Maximum
"123", "45", "6" 123, 45, 6 123
"abc", "de", "fghi" 3, 2, 4 4
"0012", "99", "a1b2c" 12, 99, 5 99

Key Observation
The heart of the problem is deciding:

“Is this string purely numeric, or not?”
Perl makes this very easy with a simple regex.

Solution

use List::Util qw(max);

sub get_value {
    my $str = shift;

    return length($str) unless $str =~ /^\d+$/;
    return 0 + $str;
}

A tiny function does all the work:

  • ^\d+$ → checks if the string is fully numeric
  • length($str) → used when it’s not
  • 0 + $str → converts "0012" into number 12 Then finding the maximum is trivial with map and max:
my $max = max(map { get_value($_) } @strings);

This is where Perl shines — very little code, very clear intent.

Challenge 2 — Caesar Cipher (Letter Shifting)

Problem
Implement a Caesar Cipher:

  • Shift every lowercase letter by N
  • Wrap around from z to a
  • Leave other characters unchanged
Input Shift Output
"abc" 1 "bcd"
"xyz" 2 "zab"
"hello" 5 "mjqqt"
"perl" 26 "perl"

Key Observation
This problem is a perfect use case for ASCII arithmetic.
Instead of thinking in terms of alphabets, think in numbers from 0 to 25.

sub caesar_encrypt {
    my ($str, $int) = @_;
    $int %= 26;

    my $result = '';
    for my $char (split //, $str) {
        if ($char =~ /[a-z]/) {
            $result .= chr(
                (ord($char) - ord('a') + $int) % 26 + ord('a')
            );
        } else {
            $result .= $char;
        }
    }
    return $result;
}

This one line does the magic:

chr((ord($char) - ord('a') + $int) % 26 + ord('a'))

Steps:

  1. Convert letter → ASCII (ord)
  2. Normalize to 0–25 range
  3. Add the shift
  4. Use modulo to wrap around
  5. Convert back to character (chr)
  6. No lookup tables. No special cases. Just math.

Testing the Solutions
For both challenges, I wrote small test cases and printed PASS/FAIL results.
This is a habit I’ve picked up from solving WPC regularly — even small scripts deserve tests.

Why I Loved These Challenges
These problems highlight why Perl is still a joy for problem solving:

  • Regex makes validation trivial
  • Numeric and string contexts work naturally
  • Character manipulation is straightforward
  • Functional tools like map make code concise
  • Very expressive in very few lines

Final Thoughts
At first glance, these look like beginner problems.
But they actually touch on important concepts:

  • Data interpretation
  • Input validation
  • ASCII math
  • Writing minimal, readable logic And Perl handles all of this elegantly.

That’s what makes the Weekly Perl Challenge so enjoyable — small puzzles, big learning.

Get them, as always, from my Wiki Haven.

As you know, The Weekly Challenge, primarily focus on Perl and Raku. During the Week #018, we received solutions to The Weekly Challenge - 018 by Orestis Zekai in Python. It was pleasant surprise to receive solutions in something other than Perl and Raku. Ever since regular team members also started contributing in other languages like Ada, APL, Awk, BASIC, Bash, Bc, Befunge-93, Bourne Shell, BQN, Brainfuck, C3, C, CESIL, Chef, COBOL, Coconut, C Shell, C++, Clojure, Crystal, CUDA, D, Dart, Dc, Elixir, Elm, Emacs Lisp, Erlang, Excel VBA, F#, Factor, Fennel, Fish, Forth, Fortran, Gembase, Gleam, GNAT, Go, GP, Groovy, Haskell, Haxe, HTML, Hy, Idris, IO, J, Janet, Java, JavaScript, Julia, K, Kap, Korn Shell, Kotlin, Lisp, Logo, Lua, M4, Maxima, Miranda, Modula 3, MMIX, Mumps, Myrddin, Nelua, Nim, Nix, Node.js, Nuweb, Oberon, Octave, OCaml, Odin, Ook, Pascal, PHP, PicoLisp, Python, PostgreSQL, Postscript, PowerShell, Prolog, R, Racket, Rexx, Ring, Roc, Ruby, Rust, Scala, Scheme, Sed, Smalltalk, SQL, Standard ML, SVG, Swift, Tcl, TypeScript, Typst, Uiua, V, Visual BASIC, WebAssembly, Wolfram, XSLT, YaBasic and Zig.

Sydney February Meeting! 2025

blogs.perl.org

Sydney Perl continues regular meetings with our next in February

Please join us on Tuesday 24th Feb 2025 at Organic Trader Pty Ltd.
Unit 13/809-821 Botany Road Rosebery

6:30pm to 9pm.

Chances are folks will head to a nearby Pub afterward.

I will talk about my 5 years working at Meta Platforms and 6 months at Amazon Inc. specifically contrasting their engineering culture, and generally discussing what Google calls an SRE culture. Contrasting my experiences at Big Tech to "Middle Tech".


Getting there:

Come in the front door marked
"Konnect" then take the first door on the right, and up the stairs to
Level 1.

Mascot station + 20 minute walk or 358 bus to Gardener's Road if you
don't want to walk so far.

Or Waterloo Metro station + 309 bus to Botany Road after Harcourt Parade.

We have a Signal group chat which we use to co-ordinate travel assistance on the day. For example, if you are lost or need a pick up from the station when it's raining etc. Reach out and someone will add you.

Join the email list!

The email list is very low volume and the place to get these updates (I sometimes forget to post them here).

Ensure to add the "from" email sydney-pm@pm.org to a custom filter and your allow-lists (and similar) to maximize chances Google/Microsoft/etc don't discard them. Plug to Australian native and Perl-ish Fastmail which is very popular and plays well.

A new sponsorship model

blogs.perl.org

Last year, I wrote that the total cost of a Perl Toolchain Summit is in the order of 50,000€. It's all covered by sponsors and attendees (and the leftovers from the previous years).

We're now preparing the Perl Toolchain Summit 2026, which will be held from Thursday, April 23rd until Sunday, April 26th, in Vienna, Austria.

Today, I'll briefly explain why we need sponsors for the event, and propose a new way to think about sponsorship to our corporate sponsors.

In the early years, attendees would pay for their accommodation and travel out of their own pocket, or maybe as a work expense, if their employer was generous enough. The only real expense the organizers had to find money for was the venue. (Technically, the hotels usually expect some advance payment when booking 30 or more rooms in advance, but that does not apply if everyone is fending for themselves.)

The participants to the summit are giving so much to the community that, since 2011, we try to cover their expenses in return. We're not paying a salary or any compensation, though. The people who attend the PTS work for free (often on their own time), and we try to ensure it doesn't cost them anything in addition to the time and effort they put in.

This is why the event needs money: to pay for the venue, to cover the attendees travel and accommodation expenses, to throw them a nice thank-you dinner. The only time we actually paid for something extra was for the 2018 Perl Toolchain in Oslo, 10 years after the original Perl QA Hackathon in Oslo. We bought everyone a sweater with a cool Perl Toolchain Summit original design.

Now, imagine you're a company whose employee has been invited to the PTS. You know they will be doing good work during their four days there, to the benefit of your business and the broader community. You'll probably send them on company time, and cover their expenses. That makes you an in-kind sponsor, for which we are very grateful, and that we acknowledge when thanking our sponsors in all our communications. (Come to think of it, how many conferences publicly thank you for sending your employees there?)

Here's a suggestion for the generous employers that send their employees to the PTS on company time and expenses: pay it forward. Estimate the cost of travel and accommodation for your employee, double it, and round it up (possibly to the next sponsorship level). Become a monetary sponsor. This will allow us to cover travel and accommodation for your employee, plus another attendee, maybe two. Or maybe just half an attendee, as travel from outside of Europe is more expensive. Who knows, there might even be some tax incentive to spend the same amount on sponsorship rather than employee expenses.

(dlxxxv) 14 great CPAN modules released last week

r/perl
Updates for great CPAN modules released last week. A module is considered great if its favorites count is greater or equal than 12.

  1. App::ccdiff - Colored Character Diff
    • Version: 0.35 on 2026-01-25, with 20 votes
    • Previous CPAN version: 0.34 was 1 year, 23 days before
    • Author: HMBRAND
  2. App::rdapper - a command-line RDAP client.
    • Version: 1.22 on 2026-01-29, with 21 votes
    • Previous CPAN version: 1.21 was 1 day before
    • Author: GBROWN
  3. App::SpeedTest - Command line interface to speedtest.net
    • Version: 0.31 on 2026-01-25, with 32 votes
    • Previous CPAN version: 0.30 was 1 year, 18 days before
    • Author: HMBRAND
  4. CPAN::Meta - the distribution metadata for a CPAN dist
    • Version: 2.150012 on 2026-01-25, with 39 votes
    • Previous CPAN version: 2.150011 was 3 days before
    • Author: RJBS
  5. CPANSA::DB - the CPAN Security Advisory data as a Perl data structure, mostly for CPAN::Audit
    • Version: 20260129.001 on 2026-01-29, with 25 votes
    • Previous CPAN version: 20260125.001 was 3 days before
    • Author: BRIANDFOY
  6. Cucumber::TagExpressions - A library for parsing and evaluating cucumber tag expressions (filters)
    • Version: 9.0.0 on 2026-01-25, with 17 votes
    • Previous CPAN version: 8.1.0 was 1 month, 29 days before
    • Author: CUKEBOT
  7. Dancer - lightweight yet powerful web application framework
    • Version: 1.3522 on 2026-01-26, with 149 votes
    • Previous CPAN version: 1.3521 was 2 years, 11 months, 18 days before
    • Author: BIGPRESH
  8. Dist::Zilla - distribution builder; installer not included!
    • Version: 6.037 on 2026-01-25, with 188 votes
    • Previous CPAN version: 6.036 was 2 months, 15 days before
    • Author: RJBS
  9. Google::Ads::GoogleAds::Client - Google Ads API Client Library for Perl
    • Version: v30.0.0 on 2026-01-28, with 20 votes
    • Previous CPAN version: v29.0.1 was 3 months, 12 days before
    • Author: CHEVALIER
  10. IO::Compress - IO Interface to compressed data files/buffers
    • Version: 2.216 on 2026-01-30, with 19 votes
    • Previous CPAN version: 2.215
    • Author: PMQS
  11. MetaCPAN::Client - A comprehensive, DWIM-featured client to the MetaCPAN API
    • Version: 2.038000 on 2026-01-29, with 27 votes
    • Previous CPAN version: 2.037000 was 22 days before
    • Author: MICKEY
  12. Net::Server - Extensible Perl internet server
    • Version: 2.016 on 2026-01-28, with 34 votes
    • Previous CPAN version: 2.015 was 5 days before
    • Author: BBB
  13. SPVM - The SPVM Language
    • Version: 0.990124 on 2026-01-31, with 36 votes
    • Previous CPAN version: 0.990123
    • Author: KIMOTO
  14. UV - Perl interface to libuv
    • Version: 2.002 on 2026-01-28, with 14 votes
    • Previous CPAN version: 2.001 was 22 days before
    • Author: PEVANS

Learn Perl or no?

r/perl

Hi, I am new to programming but I am interested in starting to code in Perl simply for the "fun" even though some describe it as hell.

I could have done a lot of research before posting, but still, just curious what Perl programmers have to say; What do you guys usually make in Perl?

submitted by /u/idonthideyoureyesdo
[link] [comments]

Perl-related GitHub organizations

Perl Maven

Most projects are started by a single person in a GitHub repository of that person. Later for various reasons people establish GitHub organizations and move the projects there. Sometimes the organization contains a set of sub-projects related to a central project. (e.g. A web framework and its extensions or database access.) Sometimes it is a collection of projects related to a single topic. (e.g. testing or IDE support.) Sometimes it is just a random collection of project where people band together in the hope that no project will be left behind. (e.g. the CPAN Authors organization.)

Organizations make it easier to have multiple maintainers and thus ensuring continuity of project, but it might also mean that none of the members really feel the urge to continue working on something.

In any case, I tried to collect all the Perl-related GitHub organizations.

Hopefully in ABC order...

  • Beyond grep - ack. No public members. 4 repositories.

  • Catalyst - Catalyst and various extensions. 10 members and 39 repositories.

  • cpan-authors - A place for CPAN authors to collaborate more easily. 4 members and 9 repositories.

  • davorg cpan - Organisation for maintaining Dave Cross's CPAN modules. No public members and 47 repositories.

  • ExifTool - No public members. 3 repositories.

  • Foswiki - The Foswiki and related projects. 13 members and 649 repositories.

  • gitpan - An archive of CPAN modules - 2 members and 5k+ read-only repositories.

  • MetaCPAN - The source of the MetaCPAN site - 9 member and 56 rpositories.

  • Mojolicious - Some Perl and many JavaScript projects. 5 members and 29 repositories.

  • Moose - Moose,MooseX-*, Moo, etc. 11 members and 69 repositories.

  • PadreIDE - Padre, the Perl IDE. 13 members and 102 repositories.

  • Paracamelus - No public members. 2 repositories.

  • Perl - Perl 5 itself, Docker images, etc. 20 members, 8 repositories.

  • Perl Actions - GitHub Actions to be used in workflows. 5 members and 9 repositories.

  • Perl Advent Calendar - including the source of perl.com. 3 members and 8 repositories.

  • Perl Toolchain Gang - ExtUtils::MakeMaker, Module::Build, etc. 27 members and 41 repositories.

  • Perl Tools Team - source of planetperl , perl-ads etc. No public members. 6 repositories.

  • Perl Dancer - Dancer, Dancer2, many plugins. 30 members and 79 repositories.

  • perltidy - Only for Perl::Tidy. No public members. 1 repository.

  • perl5-dbi - DBI, several DBD::* modules, and some related modules. 7 members and 15 repositories.

  • perl.org - also cpan.org and perldoc.perl.org. 3 members and 7 repositories.

  • Perl5 - DBIx-Class and DBIx-Class-Historic. No public members. 2 repositories.

  • perl5-utils - List::MoreUtils, File::ShareDir etc. 2 members and 22 repositories.

  • Perl-Critic - PPI, Perl::Critic and related. 7 members and 5 repositories.

  • perl-ide - Perl Development Environments. 26 members and 13 repositories.

  • perl-pod - Pod::Simple, Test::Pod. 1 member and 4 repositories.

  • plack - psgi-specs, Plack and a few middlewares. 5 members and 7 repositories.

  • RexOps - Rex, Rexify and related projects. 1 member and 46 repositories.

  • Sqitch - Sqitch for Sensible database change management and related projects. No public members. 16 repositories.

  • StrawberryPerl - The Perl distribution for MS Windows. 4 members and 10 repositories.

  • Test-More - Test::Builder, Test::Simple, Test2 etc. - 4 members, 27 repositories.

  • The Enlightened Perl Organisation - Task::Kensho and Task::Kensho::*. 1 member and 1 repository.

  • Webmin - Webmin is a web-based system administration tool for Unix-like servers. - 5 repositories.

Companies

These are bot Perl-specific GitHub organizations, but some of the repositories are in Perl.

  • cPanel - Open Source Software provided by cPanel. 1 member and 22 repositories.

  • DuckDuckGo - The search engine. 19 members and 122 repositories.

  • Fastmail - Open-source software developed at Fastmail. 4 members and 38 repositories.

  • RotherOSS - Otobo (OTRS fork). No public members. 47 repositories.

Back in 2024 I took the plunge, and submitted my first ever contribution to that year's "Perl Advent Calendar." For the past few years this has been organized/coordinated by a member of the Toronto Perl Mongers (TPM), Olaf Alders. I wrote about a solution to a challenge I had encountered at my work, and presented it as a great (simple) application of the Perl programming language. But to be honest, I believe any popular scripting language could probably have been used. I was originally a biochemist, carrying out biomedical research in a wet lab, but since retraining as a bioinformatician in 2008, Perl has almost always been the first tool that I reach for when tackling something new. The post dealt with creating phylogenetic trees for Respiratory Syncytial Virus (RSV) sequences from patients.

For the 2025 Calendar I had a couple of ideas percolating, but never found the wherewithal or gumption to actually create a new blog post. Instead, I volunteered to be a reviewer for submissions (Olaf had mentioned he could use some extra hands). Mind you, I had almost no idea what would be involved, but I figured I could teach myself.

As you may know, Advent lasts 24 days (perhaps you have enjoyed a conventional, chocolate Advent calendar in the past?) As it turned out, I think I reviewed five articles. In each case I had to teach myself about a CPAN module that the author was writing about. In all of these drafts the subject matter was outside my area of expertise, and also, outside my "comfort zone." In fact, as I mentioned to Olaf, as a sometime reader of articles and posts about Perl, I very likely would have skipped over these same blog posts. Perhaps, if I recognized the author as a prolific and popular Perl author (a celebrity), I might've thought, "I really should come back and read this over if so-and-so is writing about it . . .".

However, as I dove deep into the subject matter, read up on the relevant Perl modules, and learned about the specific "itch" that the code "scratched," I realized that it was like a mini-tutorial on something interesting, and important, that was expanding my horizons (always fun). It was very stimulating (for me), and time well spent (YMMV). In the past I have taught Scientific Writing courses for both undergrads and graduate students, but in most cases I provided very little feedback about the main content, and similarly very little feedback about the code itself. My main goal was to see if I could understand the gist of the post, and then see if I could get their code examples to run as advertised. In some cases this required installing a new Perl module (and all of its dependencies), and in other cases I also needed to install a non-Perl App, etc. These were all good things, AND revealed that I had inadvertently created a so-called "mixed" installation of different Perl versions on my MacBook Pro. Fortunately, my newfound friend, Claude AI, came to the rescue and helped me to diagnose, clear up, and clean up such glitches.

To summarize, I look forward to being an editor (reviewer) for future Perl Advent Calendars (if needed). Since helping with the 2025 Calendar, I suddenly renewed my interest in participating in "The Perl Weekly Challenge", another fun community coding activity. So from my perspective, agreeing to write that first blog post back in 2024 was basically the "gateway drug" that opened the door to learning more Perl-ish things.

100 days of Perl …

Perl on Medium

… or maybe some more ;)

Then there’s Perl

Perl on Medium

Since my native language isn’t English, the German text follows below.

I've gone through the Custom Data Labels documentation carefully, and reduced down to a simple example:

#!/usr/bin/perl
use strict;
use warnings;
use Excel::Writer::XLSX;

my $workbook  = Excel::Writer::XLSX->new( 'chart_custom_labels.xlsx' );
my $worksheet = $workbook->add_worksheet();

# Chart data
my $data = [
    [ 'Cat', 'Dog', 'Pig' ],
    [ 10, 40, 50 ],
];

$worksheet->write( 'A1', $data );

# Custom labels
my $custom_labels = [
    { value => 'Jan' },
    { value => 'Feb' },
    { value => 'Mar' },
];

my $chart = $workbook->add_chart( type => 'column' );

# Configure the series with custom string data labels
$chart->add_series(
    categories => '=Sheet1!$A$1:$A$3',
    values     => '=Sheet1!$B$1:$B$3',
    data_labels => {
        value => 1, 
        custom => $custom_labels,
    },
);

$workbook->close();

I expected this to apply labels of "Jan", "Feb", and "Mar" to the graph. However, the labels I get are just the values I would have gotten from value => 1 even if I had not included the custom labels line, i.e. 10, 40, 50:

enter image description here

I've also tried removing the value => 1 line but keeping the custom line, and that results in no labels at all. And I've tried a different approach where I keep the value => 1 line but use the delete property of custom property to remove some labels. That also did not work, and just kept the values for labels.

Is this functionality broken or am I missing something?

Environment details:

Cygwin

Perl v5.40.3

Excel::Writer::XLSX 1.03

Lock and unlock hash using Hash::Util

Perl Maven

If you don't like the autovivification or simply would like to make sure the code does not accidentally alter a hash the Hash::Util module is for you.

You can lock_hash and later you can unlock_hash if you'd like to make some changes to it.

In this example you can see 3 different actions commented out. Each one would raise an exception if someone tries to call them on a locked hash. After we unlock the hash we can execute those actions again.

I tried this both in perl 5.40 and 5.42.

examples/locking_hash.pl

use strict;
use warnings;
use feature 'say';

use Hash::Util qw(lock_hash unlock_hash);
use Data::Dumper qw(Dumper);


my %person = (
    fname => "Foo",
    lname => "Bar",
);
lock_hash(%person);

print Dumper \%person;
print "$person{fname} $person{lname}\n";
say "fname exists ", exists $person{fname};
say "language exists ", exists $person{language};

# $person{fname} = "Peti";     # Modification of a read-only value attempted
# delete $person{lname};       # Attempt to delete readonly key 'lname' from a restricted hash
# $person{language} = "Perl";  # Attempt to access disallowed key 'language' in a restricted hash

unlock_hash(%person);

$person{fname} = "Peti";     # Modification of a read-only value attempted
delete $person{lname};       # Attempt to delete readonly key 'lname' from a restricted hash
$person{language} = "Perl";  # Attempt to access disallowed key 'language' in a restricted hash

print Dumper \%person;

$VAR1 = {
          'lname' => 'Bar',
          'fname' => 'Foo'
        };
Foo Bar
fname exists 1
language exists
$VAR1 = {
          'language' => 'Perl',
          'fname' => 'Peti'
        };

Jinja2TT2: Jinja2 to Template Toolkit Transpiler

dev.to #perl

jinja2tt2 logo a tori and a camel

A Perl transpiler that converts Jinja2 templates to Template Toolkit 2 (TT2) syntax.

Source: https://github.com/lucianofedericopereira/jinja2tt2

Description

Jinja2 is deeply integrated with Python, making a direct port impractical. However, since TT2 and Jinja2 share similar concepts and syntax patterns, this transpiler performs a mechanical translation between the two template languages.

Why TT2?

TT2 and Jinja2 share:

  • Variable interpolation: {{ var }} maps to [% var %]
  • Control structures: {% if %} / {% for %} map to [% IF %] / [% FOREACH %]
  • Filters: {{ name|upper }} maps to [% name | upper %]
  • Includes, blocks, and inheritance (conceptually similar)
  • Expression grammar close enough to map mechanically

Installation

No external dependencies beyond core Perl 5.20+.

git clone https://github.com/lucianofedericopereira/jinja2tt2
cd jinja2tt2

Usage

Command Line

# Transpile a file to stdout
./bin/jinja2tt2 template.j2

# Transpile with output to file
./bin/jinja2tt2 template.j2 -o template.tt

# Transpile in-place (creates .tt file)
./bin/jinja2tt2 -i template.j2

# From stdin
echo '{{ name|upper }}' | ./bin/jinja2tt2

# Debug mode (shows tokens and AST)
./bin/jinja2tt2 --debug template.j2

Programmatic Usage

use Jinja2::TT2;

my $transpiler = Jinja2::TT2->new();

# From string
my $tt2 = $transpiler->transpile('{{ user.name|upper }}');
# Result: [% user.name.upper %]

# From file
my $tt2 = $transpiler->transpile_file('template.j2');

Supported Constructs

Variables

{{ foo }}           →  [% foo %]
{{ user.name }}     →  [% user.name %]
{{ items[0] }}      →  [% items.0 %]

Filters

{{ name|upper }}              →  [% name.upper %]
{{ name|lower|trim }}         →  [% name.lower.trim %]
{{ items|join(", ") }}        →  [% items.join(', ') %]
{{ name|default("Guest") }}   →  [% (name || 'Guest') %]

Conditionals

{% if user %}          →  [% IF user %]
{% elif admin %}       →  [% ELSIF admin %]
{% else %}             →  [% ELSE %]
{% endif %}            →  [% END %]

Loops

{% for item in items %}    →  [% FOREACH item IN items %]
{{ loop.index }}           →  [% loop.count %]
{{ loop.first }}           →  [% loop.first %]
{{ loop.last }}            →  [% loop.last %]
{% endfor %}               →  [% END %]

Blocks and Macros

{% block content %}        →  [% BLOCK content %]
{% endblock %}             →  [% END %]

{% macro btn(text) %}      →  [% MACRO btn(text) BLOCK %]
{% endmacro %}             →  [% END %]

Comments

{# This is a comment #}    →  [%# This is a comment %]

Whitespace Control

{{- name -}}               →  [%- name -%]
{%- if x -%}               →  [%- IF x -%]

Other Constructs

  • {% include "file.html" %}[% INCLUDE file.html %]
  • {% set x = 42 %}[% x = 42 %]
  • Ternary: {{ x if cond else y }}[% (cond ? x : y) %]
  • Boolean literals: true/false1/0

Filter Mapping

Jinja2 TT2 Equivalent
upper .upper
lower .lower
trim .trim
first .first
last .last
length .size
join .join
reverse .reverse
sort .sort
escape / e `\
{% raw %}default `\
{% raw %}replace .replace

Some filters require TT2 plugins (e.g., tojson needs Template::Plugin::JSON).

Loop Variable Mapping

Jinja2 TT2
loop.index loop.count
loop.index0 loop.index
loop.first loop.first
loop.last loop.last
loop.length loop.size

Limitations

  • Template inheritance ({% extends %}) requires manual adjustment for TT2's WRAPPER pattern
  • Autoescape is not directly supported in TT2
  • Some filters need custom TT2 plugins or vmethods
  • Complex Python expressions may need review

Running Tests

prove -l t/

Architecture

  1. Tokenizer: Splits Jinja2 source into tokens (text, variables, statements, comments)
  2. Parser: Builds an Abstract Syntax Tree (AST) from the token stream
  3. Emitter: Walks the AST and generates equivalent TT2 code

Credits

  • Luciano Federico Pereira - Author

License

This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) version 2.1 as published by the Free Software Foundation.

My name is Alex. Over the last years I’ve implemented several versions of the Raku’s documentation format (Synopsys 26 / Raku’s Pod) in Perl and JavaScript.

At an early stage, I shared the idea of creating a lightweight version of Raku’s Pod, with Damian Conway, the original author of the Synopsys 26 Documentation specification (S26). He was supportive of the concept and offered several valuable insights that helped shape the vision of what later became Podlite.

Today, Podlite is a small block-based markup language that is easy to read as plain text, simple to parse, and flexible enough to be used everywhere — in code, notes, technical documents, long-form writing, and even full documentation systems.

This article is an introduction for the Perl community — what Podlite is, how it looks, how you can already use it in Perl via a source filter, and what’s coming next.

The Block Structure of Podlite

One of the core ideas behind Podlite is its consistent block-based structure. Every meaningful element of a document — a heading, a paragraph, a list item, a table, a code block, a callout — is represented as a block. This makes documents both readable for humans and predictable for tools.

Podlite supports three interchangeable block styles: delimited, paragraph, and abbreviated.

Abbreviated blocks (=BLOCK)

This is the most compact form. A block starts with = followed by the block name.

=head1 Installation Guide
=item Perl 5.8 or newer
=para This tool automates the process.
  • ends on the next directive or a blank line
  • best used for simple one-line blocks
  • cannot include configuration options (attributes)

Paragraph blocks (=for BLOCK)

Use this form when you want a multi-line block or need attributes.

=for code :lang<perl>
say "Hello from Podlite!";
  • ends when a blank line appears
  • can include complex content
  • allows attributes such as :lang, :id, :caption, :nested, …

Delimited blocks (=begin BLOCK=end BLOCK)

The most expressive form. Useful for large sections, nested blocks, or structures that require clarity.

=begin nested :notify<important>
Make sure you have administrator privileges.
=end nested
  • explicit start and end markers
  • perfect for code, lists, tables, notifications, markdown, formulas
  • can contain other blocks, including nested ones

These block styles differ in syntax convenience, but all produce the same internal structure.

diagram here showing the three block styles and how they map to the same internal structure

Regardless of which syntax you choose:

  • all three forms represent the same block type
  • attributes apply the same way (:lang, :caption, :id, …)
  • tools and renderers treat them uniformly
  • nested blocks work identically
  • you can freely mix styles inside a document

Example: Comparing POD and Podlite

Let’s see how the same document looks in traditional POD versus Podlite:

POD vs Podlite

Each block has clear boundaries, so you don’t need blank lines between them. This makes your documentation more compact and easier to read. This is one of the reasons Podlite remains compact yet powerful: the syntax stays flexible, while the underlying document model stays clean and consistent.

This Podlite example rendered as on the following screen:

Podlite example

Inside the Podlite Specification 1.0

One important point about Podlite is that it is first and foremost a specification. It does not belong to any particular programming language, platform, or tooling ecosystem. The specification defines the document model, syntax rules, and semantics.

From the Podlite 1.0 specification, notable features include:

  • headings (=head1, =head2, …)
  • lists and definition lists, and including task lists
  • tables (simple and advanced)
  • CSV-backed tables
  • callouts / notifications (=nested :notify<tip|warning|important|note|caution>)
  • table of contents (=toc)
  • includes (=include)
  • embedded data (=data)
  • pictures (=picture and inline P<>)
  • formulas (=formula and inline F<>)
  • user defined blocks and markup codes
  • Markdown integration

The =markdown block is part of the standard block set defined by the Podlite Specification 1.0. This means Markdown is not an add-on or optional plugin — it is a fully integrated, first-class component of the language.

Markdown content becomes part of Podlite’s unified document structure, and its headings merge naturally with Podlite headings inside the TOC and document outline.

Below is a screenshot showing how Markdown inside Perl is rendered in the in-development VS Code extension, demonstrating both the block structure and live preview:

Podlite source, including =markdown block

Using Podlite in Perl via the source filter

To make Podlite directly usable in Perl code, there is a module on CPAN: Podlite — Use Podlite markup language in Perl programs

A minimal example could look like this:

use Podlite; # enable Podlite blocks inside Perl

=head1 Quick Example
=begin markdown
Podlite can live inside your Perl programs.
=end markdown
print "Podlite active\n";

Roadmap: what’s next for Podlite

Podlite continues to grow, and the Specification 1.0 is only the beginning. Several areas are already in active development, and more will evolve with community feedback.

Some of the things currently planned or in progress:

  • CLI tools
    • command-line utilities for converting Podlite to HTML, PDF, man pages, etc.
    • improve pipelines for building documentation sites from Podlite sources
  • VS Code integration
  • Ecosystem growth
    • develop comprehensive documentation and tutorials
    • community-driven block types and conventions

Try Podlite and share feedback

If this resonates with you, I’d be very happy to hear from you:

  • ideas for useful block types
  • suggestions for tools or integrations
  • feedback on the syntax and specification

https://github.com/podlite/podlite-specs/discussions

Even small contributions — a comment, a GitHub star, or trying an early tool — help shape the future of the specification and encourage further development.

Useful links:

Thanks for reading, Alex

This week in PSC (213) | 2026-01-26

blogs.perl.org

All three of us discussed:

  • We agree with the general idea of an improved PRNG, so we encourage Scott to continue working on the PR to get it into a polished state ready for merge
  • Haarg’s “missing import” PR now looks good; Paul has LGTM’ed it
  • TLS in core still remains a goal for the next release cycle. Crypt::OpenSSL3 might now be in a complete enough state to support a minimal viable product “https” client to be built on top of it, that could be used by an in-core CPAN client

[P5P posting of this summary]

Welcome to the Week #358 of The Weekly Challenge.
Updates for great CPAN modules released last week. A module is considered great if its favorites count is greater or equal than 12.

  1. App::Greple - extensible grep with lexical expression and region handling
    • Version: 10.03 on 2026-01-19, with 56 votes
    • Previous CPAN version: 10.02 was 10 days before
    • Author: UTASHIRO
  2. Beam::Wire - Lightweight Dependency Injection Container
    • Version: 1.028 on 2026-01-21, with 19 votes
    • Previous CPAN version: 1.027 was 1 month, 15 days before
    • Author: PREACTION
  3. CPAN::Meta - the distribution metadata for a CPAN dist
    • Version: 2.150011 on 2026-01-22, with 39 votes
    • Previous CPAN version: 2.150010 was 9 years, 5 months, 4 days before
    • Author: RJBS
  4. CPANSA::DB - the CPAN Security Advisory data as a Perl data structure, mostly for CPAN::Audit
    • Version: 20260120.004 on 2026-01-20, with 25 votes
    • Previous CPAN version: 20260120.002
    • Author: BRIANDFOY
  5. DateTime::Format::Natural - Parse informal natural language date/time strings
    • Version: 1.24 on 2026-01-18, with 19 votes
    • Previous CPAN version: 1.23_03 was 5 days before
    • Author: SCHUBIGER
  6. EV - perl interface to libev, a high performance full-featured event loop
    • Version: 4.37 on 2026-01-22, with 50 votes
    • Previous CPAN version: 4.36 was 4 months, 2 days before
    • Author: MLEHMANN
  7. Git::Repository - Perl interface to Git repositories
    • Version: 1.326 on 2026-01-18, with 27 votes
    • Previous CPAN version: 1.325 was 4 years, 7 months, 17 days before
    • Author: BOOK
  8. IO::Async - Asynchronous event-driven programming
    • Version: 0.805 on 2026-01-19, with 80 votes
    • Previous CPAN version: 0.804 was 8 months, 26 days before
    • Author: PEVANS
  9. Mac::PropertyList - work with Mac plists at a low level
    • Version: 1.606 on 2026-01-20, with 13 votes
    • Previous CPAN version: 1.605 was 5 months, 11 days before
    • Author: BRIANDFOY
  10. Module::CoreList - what modules shipped with versions of perl
    • Version: 5.20260119 on 2026-01-19, with 44 votes
    • Previous CPAN version: 5.20251220 was 29 days before
    • Author: BINGOS
  11. Net::Server - Extensible Perl internet server
    • Version: 2.015 on 2026-01-22, with 33 votes
    • Previous CPAN version: 2.014 was 2 years, 10 months, 7 days before
    • Author: BBB
  12. Net::SSH::Perl - Perl client Interface to SSH
    • Version: 2.144 on 2026-01-23, with 20 votes
    • Previous CPAN version: 2.144 was 8 days before
    • Author: BDFOY
  13. Release::Checklist - A QA checklist for CPAN releases
    • Version: 0.19 on 2026-01-25, with 16 votes
    • Previous CPAN version: 0.18 was 1 month, 15 days before
    • Author: HMBRAND
  14. Spreadsheet::Read - Meta-Wrapper for reading spreadsheet data
    • Version: 0.95 on 2026-01-25, with 31 votes
    • Previous CPAN version: 0.94 was 1 month, 15 days before
    • Author: HMBRAND
  15. SPVM - The SPVM Language
    • Version: 0.990117 on 2026-01-24, with 36 votes
    • Previous CPAN version: 0.990116
    • Author: KIMOTO
  16. utf8::all - turn on Unicode - all of it
    • Version: 0.026 on 2026-01-18, with 31 votes
    • Previous CPAN version: 0.025 was 1 day before
    • Author: HAYOBAAN

(dcxxiii) metacpan weekly report - Marlin

Niceperl

This is the weekly favourites list of CPAN distributions. Votes count: 36

Week's winner: Marlin (+3)

Build date: 2026/01/25 12:53:03 GMT


Clicked for first time:


Increasing its reputation:

See OSDC Perl

  • 00:00 Working with Peter Nilsson

  • 00:01 Find a module to add GitHub Action to. go to CPAN::Digger recent

  • 00:10 Found Tree-STR

  • 01:20 Bug in CPAN Digger that shows a GitHub link even if it is broken.

  • 01:30 Search for the module name on GitHub.

  • 02:25 Verify that the name of the module author is the owner of the GitHub repository.

  • 03:25 Edit the Makefile.PL.

  • 04:05 Edit the file, fork the repository.

  • 05:40 Send the Pull-Request.

  • 06:30 Back to CPAN Digger recent to find a module without GitHub Actions.

  • 07:20 Add file / Fork repository gives us "unexpected error".

  • 07:45 Direct fork works.

  • 08:00 Create the .github/workflows/ci.yml file.

  • 09:00 Example CI yaml file copy it and edit it.

  • 14:25 Look at a GitLab CI file for a few seconds.

  • 14:58 Commit - change the branch and add a description!

  • 17:31 Check if the GitHub Action works properly.

  • 18:17 There is a warning while the tests are running.

  • 21:20 Opening an issue.

  • 21:48 Opening the PR (on the wrong repository).

  • 22:30 Linking to output of a CI?

  • 23:40 Looking at the file to see the source of the warning.

  • 25:25 Assigning an issue? In an open source project?

  • 27:15 Edit the already created issue.

  • 28:30 USe the Preview!

  • 29:20 Sending the Pull-Request to the project owner.

  • 31:25 Switching to Jonathan

  • 33:10 CPAN Digger recent

  • 34:00 Net-SSH-Perl of BDFOY - Testing a networking module is hard and Jonathan is using Windows.

  • 35:13 Frequency of update of CPAN Digger.

  • 36:00 Looking at our notes to find the GitHub account of the module author LNATION.

  • 38:10 Look at the modules of LNATION on MetaCPAN

  • 38:47 Found JSON::Lines

  • 39:42 Install the dependencies, run the tests, generate test coverage.

  • 40:32 Cygwin?

  • 42:45 Add Github Action copying it from the previous PR.

  • 43:54 META.yml should not be committed as it is a generated file.

  • 48:25 I am looking for sponsors!

  • 48:50 Create a branch that reflects what we do.

  • 51:38 commit the changes

  • 53:10 Fork the project on GitHub and setup git remote locally.

  • 55:05 git push -u fork add-ci

  • 57:44 Sending the Pull-Request.

  • 59:10 The 7 dwarfs and Snowwhite. My hope is to have a 100 people sending these PRs.

  • 1:01:30 Feedback.

  • 1:02:10 Did you think this was useful?

  • 1:02:55 Would you be willing to tell people you know that you did this and you will do it again?

  • 1:03:17 You can put this on your resume. It means you know how to do it.

  • 1:04:16 ... and Zoom suddenly closed the recording...

See OSDC Perl

  • 00:00 Introduction and about OSDC Perl
  • 01:50 Sponsors of MetaCPAN, looking at some modules on CPAN.
  • 03:30 The river status
  • 04:10 Picking MIME::Lite and looking at MetaCPAN. Uses RT, has no GitHub Actions.
  • 05:55 Look at the clone of the repository, the 2 remotes and the 3 branches.
  • 06:40 GitHub Actions Examples
  • 08:00 Running the Docker container locally. Install the dependencies.
  • 09:10 Run the tests locally.
  • 09:20 Add the .gitignore file.
  • 10:30 Picking a module from MetaCPAN recent
  • 11:10 CPAN Digger recent
  • 12:20 Explaining about pair-programming and workshop.
  • 13:25 CPAN Digger statistics
  • 14:15 Generate test coverage report using Devel::Cover.
  • 17:15 The fold function that is not tested and not even used.
  • 18:39 Wanted to open an issue about fold, but I'll probbaly don't do it on RT.
  • 20:00 Updating the OSDC Perl document with the TODO items.
  • 21:13 Split the packages into files?
  • 22:27 The culture of Open Source contributions.
  • 24:20 Why is the BEGIN line red when the content of the block is green?
  • 27:40 Switching to the long-header branch.
  • 30:40 Finding header_as_string in the documentation.
  • 32:15 Going over the test with the long subject line.
  • 33:54 Let's compare the result to an empty string.
  • 36:15 Switching to Test::Longstring to see the difference.
  • 37:35 Test::Differences was also suggested.
  • 39:40 Push out the branch and send the Pull-request.
  • 40:35 Did this really increase the test coverage? Let's see it.
  • 43:50 Messing up the explanation about codition coverage.
  • 45:35 The repeated use of the magic number 72.
  • 47:00 Is the output actually correct? Is it according to the standard?
  • 51:45 Discussion about /usr/bin/perl on the first line.
  • 52:45 No version is specified.
  • 55:15 The sentence should be "conforms to the standard"

Announcing the Perl Toolchain Summit 2026!

The organizers have been working behind the scenes since last September, and today I’m happy to announce that the 16th Perl Toolchain Summit will be held in Vienna, Austria, from Thursday April 23rd till Sunday April 26th, 2026.

This post is brought to you by Simplelists, a group email and mailing list service provider, and a recurring sponsor of the Perl Toolchain Summit.

Simplelists logo


Started in 2008 as the Perl QA Hackathon in Oslo, the Perl Toolchain Summit is an annual event that brings together the key developers working on the Perl toolchain. Each year (except for 2020-2022), the event moves from country to country all over Europe, organised by local teams of volunteers. The surplus money from previous summits helps fund the next one.

Since 2023, the organizing team is formally split between a “global” team and a “local” team (although this setup has been informally used before).

The global team is made up of veteran PTS organizers, who deal with invitations, finding sponsors, paying bills and communications. They are Laurent Boivin (ELBEHO), Philippe Bruhat (BOOK), Thibault Duponchelle (CONTRA), Tina Müller (TINITA) and Breno de Oliveira (GARU), supported by Les Mongueurs de Perl’s bank account.

The local team members for this year have organized several events in Vienna (including the Perl QA Hackathon 2010!) and deal with finding the venue, the hotel, the catering and welcoming our attendees in Vienna in April. They are Alexander Hartmaier (ABRAXXA), Thomas Klausner (DOMM), Maroš Kollár (MAROS), Michael Kröll and Helmut Wollmersdorfer (WOLLMERS).

The developers who maintain CPAN and associated tools and services are all volunteers, scattered across the globe. This event is the one time in the year when they can get together.

The summit provides dedicated time to work on the critical systems and tools, with all the right people in the same room. The attendees hammer out solutions to thorny problems and discuss new ideas to keep the toolchain moving forward. This year, about 40 people have been invited, with 35 participants expected to join us in Vienna.

If you want to find out more about the work being done at the Toolchain Summit, and hear the teams and people involved, you can listen to several episodes of The Underbar podcast, which were recorded during the 2025 edition in Leipzig, Germany:

Given the important nature of the attendees’ work and their volunteer status, we try to pay for most expenses (travel, lodging, food, etc.) through sponsorship. If you’re interested in helping sponsor the summit, please get in touch with the global team at pts2026@perltoolchainsummit.org.

Simplelists has been sponsoring the Perl Toolchain Summit for several years now. We are very grateful for their continued support.

Simplelists is proud to sponsor the 2026 Perl Toolchain Summit, as Perl forms the core of our technology stack. We are grateful that we can rely on the robust and comprehensive Perl ecosystem, from the core of Perl itself to a whole myriad of CPAN modules. We are glad that the PTS continues its unsung work, ensuring that Simplelists can continue to rely on these many tools.

Leveraging Gemini CLI and the underlying Gemini LLM to build Model Context Protocol (MCP) AI applications in Perl with Google Cloud Run.

Updates for great CPAN modules released last week. A module is considered great if its favorites count is greater or equal than 12.

  1. CPANSA::DB - the CPAN Security Advisory data as a Perl data structure, mostly for CPAN::Audit
    • Version: 20260110.003 on 2026-01-11, with 25 votes
    • Previous CPAN version: 20260104.001 was 6 days before
    • Author: BRIANDFOY
  2. FFI::Platypus - Write Perl bindings to non-Perl libraries with FFI. No XS required.
    • Version: 2.11 on 2026-01-12, with 69 votes
    • Previous CPAN version: 2.10 was 1 year, 24 days before
    • Author: PLICEASE
  3. Firefox::Marionette - Automate the Firefox browser with the Marionette protocol
    • Version: 1.70 on 2026-01-11, with 18 votes
    • Previous CPAN version: 1.69 was before
    • Author: DDICK
  4. Module::Starter - a simple starter kit for any module
    • Version: 1.82 on 2026-01-10, with 34 votes
    • Previous CPAN version: 1.81 was before
    • Author: XSAWYERX
  5. Net::DNS - Perl Interface to the Domain Name System
    • Version: 1.54 on 2026-01-16, with 29 votes
    • Previous CPAN version: 1.53 was 4 months, 18 days before
    • Author: NLNETLABS
  6. Net::SSH::Perl - Perl client Interface to SSH
    • Version: 2.144 on 2026-01-14, with 20 votes
    • Previous CPAN version: 2.143 was 1 year, 10 days before
    • Author: BRIANDFOY
  7. Sidef - The Sidef Programming Language - A modern, high-level programming language
    • Version: 26.01 on 2026-01-13, with 121 votes
    • Previous CPAN version: 25.12 was 23 days before
    • Author: TRIZEN
  8. Sys::Virt - libvirt Perl API
    • Version: v12.0.0 on 2026-01-16, with 17 votes
    • Previous CPAN version: v11.10.0 was 1 month, 14 days before
    • Author: DANBERR
  9. utf8::all - turn on Unicode - all of it
    • Version: 0.025 on 2026-01-16, with 30 votes
    • Previous CPAN version: 0.024 was 8 years, 11 days before
    • Author: HAYOBAAN

(dcxxii) metacpan weekly report - Marlin

Niceperl

This is the weekly favourites list of CPAN distributions. Votes count: 89

Week's winner: Marlin (+6)

Build date: 2026/01/18 10:13:31 GMT


Clicked for first time:


Increasing its reputation:

JSON parse array of data

Perl questions on StackOverflow

I have the following program with JSON:

use strict;
use warnings;

use Data::Dumper qw( );
use JSON qw( );

my $json_text = '[
  {
    "sent": "2026-01-16T17:00:00Z",
    "data": [
      {
        "headline": "text1",
        "displayText": "text2"
      },
      {
        "displayText": "text3"
      },
      {
        "displayText": "text4"
      }
    ]
  },
  {
    "sent": "2026-01-16T17:00:00Z",
    "data": [
      {
        "headline": "text5",
        "displayText": "text6"
      },
      {
        "displayText": "text7"
      },
      {
        "displayText": "text8"
      },
      {
        "headline": "text9",
        "displayText": "text10"
      }
    ]
  }
]';

my $json = JSON->new;
my $data = $json->decode($json_text);

print Data::Dumper->Dump($data);

# This is pseudocode:
foreach ( $data->[] ) {
    print "\$_ is $_";
}

I would like to walk through elements in JSON and find all sent and all displayText values. But, I do not know how to dereference first element. First element is array without any name in this case.

Leveraging Gemini CLI and the underlying Gemini LLM to build Model Context Protocol (MCP) AI applications in Perl with a local development…

Leveraging Gemini CLI and the underlying Gemini LLM to build Model Context Protocol (MCP) AI applications in Perl with Google Cloud Run.


Dave writes:

During December, I fixed assorted bugs, and started work on another tranche of ExtUtils::ParseXS fixups, this time focussing on:

  • adding and rewording warning and error messages, and adding new tests for them;

  • improving test coverage: all XS keywords have tests now;

  • reorganising the test infrastructure: deleting obsolete test files, renaming the t/*.t files to a more consistent format; splitting a large test file; modernising tests;

  • refactoring and improving the length(str) pseudo-parameter implementation.

By the end of this report period, that work was about half finished; it is currently finished and being reviewed.

Summary: * 10:25 GH #16197 re eval stack unwinding * 1:39 GH #23903 BBC: bleadperl breaks ETHER/Package-Stash-XS-0.30.tar.gz * 0:09 GH #23986 Perl_rpp_popfree_to(SV sp**) questionable design * 3:02 fix Pod::Html stderr noise * 27:47 improve Extutils::ParseXS * 1:47 modernise perlxs.pod

Total: * 44:49 (HH::MM)


Tony writes:

``` [Hours] [Activity] 2025/12/01 Monday 0.23 memEQ cast discussion with khw 0.42 #23965 testing, review and comment 2.03 #23885 review, testing, comments 0.08 #23970 review and approve 0.13 #23971 review and approve

0.08 #23965 follow-up

2.97

2025/12/02 Tuesday 0.73 #23969 research and comment 0.30 #23974 review and approve 0.87 #23975 review and comment 0.38 #23975 review reply and approve 0.25 #23976 review, research and approve 0.43 #23977 review, research and approve

1.20 #23918 try to produce expected bug and succeed

4.16

2025/12/03 Wednesday 0.35 #23883 check updates and approve with comment 0.72 #23979 review, try to trigger the messages and approve 0.33 #23968 review, research and approve 0.25 #23961 review and comment 2.42 #23918 fix handling of context, testing, push to update,

comment on overload handling plans, start on it

4.07

2025/12/04 Thursday 2.05 #23980 review, comment and approve, fix group_end() decorator and make PR 23983 0.25 #23982 review, research and approve 1.30 #23918 test for skipping numeric overload, and fix, start

on force overload

3.60

2025/12/05 Friday

0.63 #23980 comment

0.63

2025/12/08 Monday 0.90 #23984 review and comment 0.13 #23988 review and comment 2.03 #23918 work on force overload implmentation

1.45 #23918 testing, docs

4.51

2025/12/09 Tuesday 0.32 github notifications 1.23 #23918 add more tests 0.30 #23992 review 0.47 #23993 research, testing and comment

0.58 #23993 review and comment

2.90

2025/12/10 Wednesday 0.72 #23992 review updates, testing and comment 1.22 #23782 review (and some #23885 discussion in irc) 1.35 look into Jim’s freebsd core dump, reproduce and find cause, email him and briefly comment in irc, more 23885

discussion and approve 23885

3.29

2025/12/11 Thursday 0.33 #23997 comment 1.08 #23995 research and comment 0.47 #23998 review and approve

1.15 #23918 cleanup

3.03

2025/11/15 Saturday 0.20 #23998 review updates and approve 0.53 #23975 review comment, research and follow-up 1.25 #24002 review discussion, debugging and comment 0.28 #23993 comment 0.67 #23918 commit cleanup 0.20 #24002 follow-up

0.65 #23975 research and follow-up

3.78

2025/12/16 Tuesday 0.40 #23997 review, comment, approve 0.37 #23988 review and comment 0.95 #24001 debugging and comment 0.27 #24006 review and comment 0.23 #24004 review and nothing to say

1.27 #23918 more cleanup, documentation

3.49

2025/12/17 Wednesday 0.32 #24008 testing, debugging and comment 0.08 #24006 review update and approve 0.60 #23795 quick re-check and approve 1.02 #23918 more fixes, address each PR comment and push for CI 0.75 #23956 work on a test and a fix, push for CI 0.93 #24001 write a test, and a fix, testing 0.67 #24001 write an inverted test too, commit message and push for CI 0.17 #23956 perldelta 0.08 #23956 check CI results, make PR 24010

0.15 #24001 perldelta and make PR 24011

4.77

2025/12/18 Thursday 0.27 #24001 rebase, local testing, push for CI 1.15 #24012 research 0.50 #23995 testing and comment

0.08 #24001 check CI results and apply to blead

2.00

Which I calculate is 43.2 hours.

Approximately 32 tickets were reviewed or worked on, and 1 patches were applied. ```


Paul writes:

A mix of focus this month. I was hoping to get attributes-v2 towards something that could be reviewed and merged, but then I bumped into a bunch of refalias-related issues. Also spent about 5 hours reviewing Dave's giant xspod rewrite.

  • 1 = Rename THING token in grammar to something more meaningful
    • https://github.com/Perl/perl5/pull/23982
  • 4 = Continue work on attributes-v2
  • 1 = BBC Ticket on Feature-Compat-Class
    • https://github.com/Perl/perl5/issues/23991
  • 2 = Experiment with refalias parameters with defaults in XS-Parse-Sublike
  • 1 = Managing the PPC documents and overall process
  • 2 = Investigations into the refalias and declared_refs features, to see if we can un-experiment them
  • 2 = Add a warning to refalias that breaks closures
    • https://github.com/Perl/perl5/pull/24026 (work-in-progress)
  • 3 = Restore refaliased variables after foreach loop
    • https://github.com/Perl/perl5/issues/24028
    • https://github.com/Perl/perl5/pull/24029
  • 3 = Clear pad after multivariable foreach
    • https://github.com/Perl/perl5/pull/24034 (not yet merged)
  • 6 = Github code reviews (mostly on Dave's xspod)
    • https://github.com/Perl/perl5/pull/23795

Total: 25 hours

In a script I'm using constants (use constant ...) to allow re-use ion actual regular expressions, using the pattern from https://stackoverflow.com/a/69379743/6607497. However when using a {...} repeat specifier following such constant expansion, Perl wants to tread the constant as a hash variable.

The question is how to avoid that.

Code example:

main::(-e:1):   1
  DB<1> use constant CHARSET => '[[:graph:]]'

  DB<2> x "foo" =~ qr/^[[:graph:]]{3,}$/
0  1
  DB<3> x "foo" =~ qr/^${\CHARSET}{3,}$/
Not a HASH reference at (eval 8)[/usr/lib/perl5/5.26.1/perl5db.pl:738] line 2.
  DB<4> x "foo" =~ qr/^${\CHARSET}\{3,}$/
  empty array
  DB<5> x $^V
0  v5.26.1

According to https://stackoverflow.com/a/79845011/6607497 a solution may be to add a space that's being ignored, like this: qr/^${\CHARSET} {3,}$/x; however I don't understand why this works, because outside of a regular expression the space before { is being ignored:

  DB<6> x "foo" =~ qr/^${\CHARSET} {3,}$/x
0  1
  DB<7> %h = (a => 3)

  DB<8> x $h{a}
0  3
  DB<9> x $h {a}
0  3

The manual page (perlop(1) on "Quote and Quote-like Operators") isn't very precise on that:

For constructs that do interpolate, variables beginning with "$" or "@" are interpolated. Subscripted variables such as $a[3] or "$href->{key}[0]" are also interpolated, as are array and hash slices. But method calls such as "$obj->meth" are not.

App::HTTPThis: the tiny web server I keep reaching for

Perl Hacks

Whenever I’m building a static website, I almost never start by reaching for Apache, nginx, Docker, or anything that feels like “proper infrastructure”. Nine times out of ten I just want a directory served over HTTP so I can click around, test routes, check assets, and see what happens in a real browser.

For that job, I’ve been using App::HTTPThis for years.

It’s a simple local web server you run from the command line. Point it at a directory, and it serves it. That’s it. No vhosts. No config bureaucracy. No “why is this module not enabled”. Just: run a command and you’ve got a website.

Why I’ve used it for years

Static sites are deceptively simple… right up until they aren’t.

  • You want to check that relative links behave the way you think they do.

  • You want to confirm your CSS and images are loading with the paths you expect.

  • You want to reproduce “real HTTP” behaviour (caching headers, MIME types, directory handling) rather than viewing files directly from disk.

Sure, you can open file:///.../index.html in a browser, but that’s not the same thing as serving it over HTTP. And setting up Apache (or friends) feels like bringing a cement mixer to butter some toast.

With http_this, the workflow is basically:

  • cd into your site directory

  • run a single command

  • open a URL

  • get on with your life

It’s the “tiny screwdriver” that’s always on my desk.

Why I took it over

A couple of years ago, the original maintainer had (entirely reasonably!) become too busy elsewhere and the distribution wasn’t getting attention. That happens. Open source is like that.

But I was using App::HTTPThis regularly, and I had one small-but-annoying itch: when you visited a directory URL, it would always show a directory listing – even if that directory contained an index.html. So instead of behaving like a typical web server (serve index.html by default), it treated index.html as just another file you had to click.

That’s exactly the sort of thing you notice when you’re using a tool every day, and it was irritating enough that I volunteered to take over maintenance.

(If you want to read more on this story, I wrote a couple of blog posts.)

What I’ve done since taking it over

Most of the changes are about making the “serve a directory” experience smoother, without turning it into a kitchen-sink web server.

1) Serve index pages by default (autoindex)

The first change was to make directory URLs behave like you’d expect: if index.html exists, serve it automatically. If it doesn’t, you still get a directory listing.

2) Prettier index pages

Once autoindex was in place, I then turned my attention to the fallback directory listing page. If there isn’t an index.html, you still need a useful listing — but it doesn’t have to look like it fell out of 1998. So I cleaned up the listing output and made it a bit nicer to read when you do end up browsing raw directories.

3) A config file

Once you’ve used a tool for a while, you start to realise you run it the same way most of the time.

A config file lets you keep your common preferences in one place instead of re-typing options. It keeps the “one command” feel, but gives you repeatability when you want it.

4) --host option

The ability to control the host binding sounds like an edge case until it isn’t.

Sometimes you want:

  • only localhost access for safety;

  • access from other devices on your network (phone/tablet testing);

  • behaviour that matches a particular environment.

A --host option gives you that control without adding complexity to the default case.

The Bonjour feature (and what it’s for)

This is the part I only really appreciated recently: App::HTTPThis can advertise itself on your local network using mDNS / DNS-SD – commonly called Bonjour on Apple platforms, Avahi on Linux, and various other names depending on who you’re talking to.

It’s switched on with the --name option.

http_this --name MyService

When you do that, http_this publishes an _http._tcp service on your local network with the instance name you chose (MyService in this case). Any device on the same network that understands mDNS/DNS-SD can then discover it and resolve it to an address and port, without you having to tell anyone, “go to http://192.168.1.23:7007/”.

Confession time: I ignored this feature for ages because I’d mentally filed it under “Apple-only magic” (Bonjour! very shiny! probably proprietary!). It turns out it’s not Apple-only at all; it’s a set of standard networking technologies that are supported on pretty much everything, just under a frankly ridiculous number of different names. So: not Apple magic, just local-network service discovery with a branding problem.

Because I’d never really used it, I finally sat down and tested it properly after someone emailed me about it last week, and it worked nicely, nicely enough that I’ve now added a BONJOUR.md file to the repo with a practical explanation of what’s going on, how to enable it, and a few ways to browse/discover the advertised service.

(If you’re curious, look for _http._tcp and your chosen service name.)

It’s a neat quality-of-life feature if you’re doing cross-device testing or helping someone else on the same network reach what you’re running.

Related tools in the same family

App::HTTPThis is part of a little ecosystem of “run a thing here quickly” command-line apps. If you like the shape of http_this, you might also want to look at these siblings:

  • https_this : like http_this, but served over HTTPS (useful when you need to test secure contexts, service workers, APIs that require HTTPS, etc.)

  • cgi_this : for quick CGI-style testing without setting up a full web server stack

  • dav_this : serves content over WebDAV (handy for testing clients or workflows that expect DAV)

  • ftp_this : quick FTP server for those rare-but-real moments when you need one

They all share the same basic philosophy: remove the friction between “I have a directory” and “I want to interact with it like a service”.

Wrapping up

I like tools that do one job, do it well, and get out of the way. App::HTTPThis has been that tool for me for years and it’s been fun (and useful) to nudge it forward as a maintainer.

If you’re doing any kind of static site work — docs sites, little prototypes, generated output, local previews — it’s worth keeping in your toolbox.

And if you’ve got ideas, bug reports, or platform notes (especially around Bonjour/Avahi weirdness), I’m always happy to hear them.

The post App::HTTPThis: the tiny web server I keep reaching for first appeared on Perl Hacks.