
Perl Patterns
Write and refactor Perl 5.36+ modules with signatures, modern pragmas, and testable boundaries instead of legacy boilerplate.
Overview
Perl Patterns is an agent skill for the Build phase that applies modern Perl 5.36+ idioms, signatures, and module architecture for robust applications.
Install
npx skills add https://github.com/affaan-m/everything-claude-code --skill perl-patternsWhat is this skill?
- Modern preamble with use v5.36 replacing strict/warnings/signatures boilerplate
- Subroutine signatures with defaults and arity checking
- Module layout, error-handling, and testable boundary patterns for maintainable Perl
- Refactoring and migration guidance from pre-5.36 legacy code
- Copy-paste examples meant as starting points tuned to your deployment model
- Targets Perl 5.36+ with use v5.36 preamble
Adoption & trust: 4k installs on skills.sh; 210k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent (or you) keeps emitting legacy Perl boilerplate and untestable subs instead of v5.36 signatures and clear module boundaries.
Who is it for?
Maintaining Perl services, CLIs, or CPAN-style modules and migrating older code toward 5.36+ standards.
Skip if: Greenfield projects where you have already standardized on another language stack with no Perl in production.
When should I use this skill?
Writing new Perl code or modules, reviewing Perl for idiom compliance, refactoring legacy Perl, designing module architecture, or migrating pre-5.36 code.
What do I get? / Deliverables
New and refactored Perl code follows consistent modern defaults—v5.36, signatures, and maintainable error and module patterns you can review in PRs.
- Idiomatic Perl modules and subs using signatures and v5.36
- Refactor plans from legacy Perl to modern structure
Recommended Skills
Journey fit
Perl module and service work happens while you are implementing server-side logic, CLIs, and integrations. Backend is the canonical shelf for idiomatic Perl application and module architecture patterns.
How it compares
Idiom and architecture guidance for Perl repos—not a Raku/PHP linter integration or a one-shot script generator.
Common Questions / FAQ
Who is perl-patterns for?
Developers and indie operators shipping Perl backends, automation, or modules who want agent output to match modern Perl community defaults.
When should I use perl-patterns?
Use it during Build when authoring Perl modules, reviewing PRs, refactoring legacy Perl, or planning package layout before implementation.
Is perl-patterns safe to install?
It provides coding conventions only; review the Security Audits panel on this page and keep dependency and secrets handling in your normal toolchain.
SKILL.md
READMESKILL.md - Perl Patterns
# Modern Perl Development Patterns Idiomatic Perl 5.36+ patterns and best practices for building robust, maintainable applications. ## When to Activate - Writing new Perl code or modules - Reviewing Perl code for idiom compliance - Refactoring legacy Perl to modern standards - Designing Perl module architecture - Migrating pre-5.36 code to modern Perl ## How It Works Apply these patterns as a bias toward modern Perl 5.36+ defaults: signatures, explicit modules, focused error handling, and testable boundaries. The examples below are meant to be copied as starting points, then tightened for the actual app, dependency stack, and deployment model in front of you. ## Core Principles ### 1. Use `v5.36` Pragma A single `use v5.36` replaces the old boilerplate and enables strict, warnings, and subroutine signatures. ```perl # Good: Modern preamble use v5.36; sub greet($name) { say "Hello, $name!"; } # Bad: Legacy boilerplate use strict; use warnings; use feature 'say', 'signatures'; no warnings 'experimental::signatures'; sub greet { my ($name) = @_; say "Hello, $name!"; } ``` ### 2. Subroutine Signatures Use signatures for clarity and automatic arity checking. ```perl use v5.36; # Good: Signatures with defaults sub connect_db($host, $port = 5432, $timeout = 30) { # $host is required, others have defaults return DBI->connect("dbi:Pg:host=$host;port=$port", undef, undef, { RaiseError => 1, PrintError => 0, }); } # Good: Slurpy parameter for variable args sub log_message($level, @details) { say "[$level] " . join(' ', @details); } # Bad: Manual argument unpacking sub connect_db { my ($host, $port, $timeout) = @_; $port //= 5432; $timeout //= 30; # ... } ``` ### 3. Context Sensitivity Understand scalar vs list context — a core Perl concept. ```perl use v5.36; my @items = (1, 2, 3, 4, 5); my @copy = @items; # List context: all elements my $count = @items; # Scalar context: count (5) say "Items: " . scalar @items; # Force scalar context ``` ### 4. Postfix Dereferencing Use postfix dereference syntax for readability with nested structures. ```perl use v5.36; my $data = { users => [ { name => 'Alice', roles => ['admin', 'user'] }, { name => 'Bob', roles => ['user'] }, ], }; # Good: Postfix dereferencing my @users = $data->{users}->@*; my @roles = $data->{users}[0]{roles}->@*; my %first = $data->{users}[0]->%*; # Bad: Circumfix dereferencing (harder to read in chains) my @users = @{ $data->{users} }; my @roles = @{ $data->{users}[0]{roles} }; ``` ### 5. The `isa` Operator (5.32+) Infix type-check — replaces `blessed($o) && $o->isa('X')`. ```perl use v5.36; if ($obj isa 'My::Class') { $obj->do_something } ``` ## Error Handling ### eval/die Pattern ```perl use v5.36; sub parse_config($path) { my $content = eval { path($path)->slurp_utf8 }; die "Config error: $@" if $@; return decode_json($content); } ``` ### Try::Tiny (Reliable Exception Handling) ```perl use v5.36; use Try::Tiny; sub fetch_user($id) { my $user = try { $db->resultset('User')->find($id) // die "User $id not found\n"; } catch { warn "Failed to fetch user $id: $_"; undef; }; return $user; } ``` ### Native try/catch (5.40+) ```perl use v5.40; sub divide($x, $y) { try { die "Division by zero" if $y == 0; return $x / $y; } catch ($e) { warn "Error: $e"; return; } } ``` ## Modern OO with Moo Prefer Moo for lightweight, modern OO. Use Moose only when its metaprotocol is needed. ```perl # Good: Moo class package User; use Moo; use Types::Standard qw(Str Int ArrayRef); use namespace::autoclean; has name => (is => 'ro', isa => Str, required => 1); has email