App-karr
view release on metacpan or search on metacpan
.claude/skills/perl-core/SKILL.md view on Meta::CPAN
```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.
### Methods, not bare subs
- **In a Moose class, every helper is a method on `$self`.** Not a bare `sub _foo { ... }` invoked as `_foo($self->goldmine, $x)`. The class is there; use it.
- **Per-process caches go on the singleton as a Moose attribute** (`has _cache => ( is => 'ro', default => sub { {} } )`), not a `my %CACHE` package variable. Survives test isolation, lets a future caller swap state per instance.
- **No package-level state** unless it's a true global (an `%ENGINE_CLASS` lookup table that's literally constant counts; a per-call cache does not).
- Bare subs are OK in **non-class utility modules** that are imported as functions (`Goldmine::I18n::gm_key`, `Goldmine::BlockerReason::blocker`). Once a file says `use Moose` / `use MooseX::Singleton`, every `sub` should be a method.
.claude/skills/perl-moo/SKILL.md view on Meta::CPAN
warnings->import::into($target);
Moo->import::into($target);
namespace::clean->import::into($target); # after Moo, cleans stray imports
}
package App::Thing;
use My::Mooish;
has x => (is => 'ro', default => sub { 1 });
```
**Rules:** Order matters: imports â `use Moo` â `namespace::clean`. Use `namespace::autoclean` ⥠0.16 only (older versions inflate Moo classes to Moose). Use `strictures` v2 with Moo 2.
---
## Pattern 5 â Delegation via `handles`
```perl
package App::UsesCounter;
use Moo;
has counter => (
is => 'ro',
.claude/skills/perl-moo/SKILL.md view on Meta::CPAN
| Legacy non-Moo parent | `FOREIGNBUILDARGS` |
| Multiple inheritance | Last resort; use `mro 'c3'` |
---
## Common Pitfalls
- `default => []` â **shared state bug**. Always `default => sub { [] }`.
- `extends 'A'; extends 'B'` â replaces, does NOT add B to A. Use `extends 'A', 'B'`.
- Imports after `use Moo::Role` are **composed into consumers** as methods.
- `namespace::autoclean` < 0.16 inflates Moo classes to Moose unexpectedly.
- `trigger` does NOT receive old value (unlike Moose).
- `Sub::HandlesVia` must be loaded *after* `use Moo`.
- `BUILD` chain is automatic; calling `SUPER::BUILD` manually breaks it.
- Never override `DESTROY`; use `DEMOLISH`.
( run in 2.124 seconds using v1.01-cache-2.11-cpan-0bb4e1dffa6 )