App-Raider
view release on metacpan or search on metacpan
.claude/skills/perl-core/SKILL.md view on Meta::CPAN
---
name: perl-core
description: Getty's house rules for all Perl code â module loading, Moose patterns, cpanfile versioning for Getty-authored CPAN distributions, stylistic choices that differ from defaults. Load on any Perl edit in a Getty project.
---
# Perl Core â Getty House Rules
These rules override defaults. They are non-negotiable in Getty projects.
## Module loading
- **`use Module;` at the top.** Always. Every dependency is loaded at compile time.
- **`require` is forbidden as a "lazy optimization".** Never use it to shave startup. If you find yourself writing `require Foo;` inside a method body, stop. Move it to a top-level `use`.
- **`require` is allowed ONLY for true runtime plugin loading** â i.e. the class to load is determined from config/DB at runtime (e.g. `Module::Runtime::use_module($class_from_db)`). If the class name is known at write-time, `use` it.
- **`require` + `->new` directly in a controller action** is a red flag. Fix by hoisting to `use` at the top of the file.
## Singletons
- **`->instance`** for classes that use `MooseX::Singleton` or `MooX::Singleton`. Never call `->new` on a singleton.
- **`->new`** for everything else.
## Getty CPAN distributions â cpanfile versioning
Getty's dist.ini uses `[@Author::GETTY]`, which sets `$VERSION` in the repo to the **next, unreleased** version (e.g. `0.402` while CPAN is at `0.401`). The repo is ALWAYS ahead of CPAN by one.
**Rules:**
1. **NEVER copy a version number from a Getty-authored repo into a `cpanfile`.** The repo version is not released. `cpanm` cannot install it. Your build will break.
2. **Check `cpanm --info Module::Name`** (or CPAN / MetaCPAN) to get the actual released version.
3. **Every Getty-authored distribution listed in our project cpanfiles must be pinned to the latest released version on CPAN.** Not `'0'`, not some stale number â the current latest. Check with `cpanm --info` before writing the requires line.
4. **Re-check on upgrade.** When bumping, use `cpanm --info` again.
Getty-authored examples (non-exhaustive): `Langertha`, `IO::K8s`, `Kubernetes::REST`, `WWW::Firecrawl`, `Net::Async::Firecrawl`, `Net::Async::WebSearch`, `Catalyst::Plugin::ChainedURI`, `Locale::Simple`, `DBIO::*`, `WWW::Zitadel`, `WWW::PayPal`, `WWW...
Quick check for unknown modules:
```bash
cpanm --info Module::Name | tail -1
# â GETTY/Module-Name-1.234.tar.gz â pin to 1.234
```
## Moose / OOP style
- **`lazy_build => 1` + `sub _build_foo`** is strongly preferred over `default => sub { ... }` for anything non-trivial. Keeps attribute declarations clean.
- **`weak_ref => 1`** on attributes that hold a reference back to a parent/owner object. Standard for nested Moose object graphs â prevents circular refs.
- **`namespace::autoclean`** on every class file. For classes that extend DBIx::Class (`MooseX::NonMoose` pattern), use **`MooseX::MarkAsMethods autoclean => 1`** instead.
- **`no Moose;` + `__PACKAGE__->meta->make_immutable;`** at the bottom of every Moose class.
- **`my ( $self ) = @_;`** â explicit destructure, not `my $self = shift;`. Space inside the parens.
- **Explicit import lists with `qw( ... )`** â `use Foo qw( bar baz );`. Never rely on default exports unless they're documented as stable.
## Style / whitespace
- **2-space indentation.** Not 4. Not tabs. Every Getty Perl file.
- **No trailing commas** at the end of multi-line lists (different from Python convention).
## File I/O
- **`Path::Tiny`** for every file operation. Not `File::Spec`, not bare `open`. Method-chain: `path(...)->child(...)->slurp_utf8`.
## JSON
- **`JSON::MaybeXS`** always. When encoding, set `canonical => 1, convert_blessed => 1` on the encoder object.
## Forbidden / anti-patterns
- â `require Foo` inside a method to "speed up startup"
- â Using `$VERSION` from a Getty repo as the cpanfile requirement
- â `default => sub { ... }` for a non-trivial Moose attribute default (use `lazy_build`)
- â 4-space indent in new Perl files
- â `File::Spec` in new code
- â `Data::Dumper` in shipped code (use `DDP` / `Data::Printer` for debug, strip before commit)
## When in doubt
Grep an existing Getty project (`~/dev/perl/ellis/edge/`, `~/dev/perl/langertha/`, `~/dev/perl/shore/`) for how the pattern is used there. That is the ground truth.
( run in 1.203 second using v1.01-cache-2.11-cpan-9581c071862 )