App-Raider
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.
## 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
.claude/skills/perl-moose/SKILL.md view on Meta::CPAN
## Core Principle
Use **inheritance sparingly** (stable "is-a" contracts), **roles heavily** (horizontal reuse). When in doubt: role, not subclass. Always end classes with `make_immutable`.
---
## Pattern 1 â `extends` + Attribute Override
```perl
package Vehicle;
use Moose;
use namespace::autoclean;
has color => (is => 'ro', default => 'black');
__PACKAGE__->meta->make_immutable;
package Spaceship;
use Moose;
use namespace::autoclean;
extends 'Vehicle';
has '+color' => (default => 'silver'); # override via +attr
__PACKAGE__->meta->make_immutable;
```
**Rules:**
- Multiple `extends` calls REPLACE (don't add) â always `extends 'A', 'B'` in one call.
- Override inherited attributes with `has '+name' => (...)` â don't redefine from scratch.
- Never override `isa` type in a subclass (global side effects).
- Moose uses C3 linearization for diamond inheritance â deterministic MRO.
.claude/skills/perl-moose/SKILL.md view on Meta::CPAN
## Pattern 2 â Role with `requires`
```perl
package Role::Printable;
use Moose::Role;
requires 'to_string'; # contract: consumer must implement this
sub print_self { print $_[0]->to_string, "\n" }
package Document;
use Moose;
use namespace::autoclean;
with 'Role::Printable';
sub to_string { "Document: " . $_[0]->title }
has title => (is => 'ro', required => 1);
__PACKAGE__->meta->make_immutable;
```
**Rules:**
- `requires` fails at composition time, not runtime â loud and early.
- Always compose all roles **in one `with` call** â separate `with` calls skip conflict detection.
- `with` must come **after** all `has` declarations the role might need.
- `excludes => 'OtherRole'` prevents composing two incompatible roles â use sparingly.
---
## Pattern 3 â Role Conflict Resolution
```perl
# Both roles define foo() â conflict â class must resolve it
package MyClass;
use Moose;
use namespace::autoclean;
with 'RoleA', 'RoleB'; # dies if both define foo() without resolution
sub foo { ... } # class defines foo â wins, resolves conflict
# Alternative: alias + exclude
with 'RoleA' => { -alias => { foo => 'foo_a' }, -excludes => 'foo' },
'RoleB'; # RoleB's foo wins; RoleA's available as foo_a
__PACKAGE__->meta->make_immutable;
```
**Rules:** Moose does NOT silently pick a winner â conflicts are fatal. Class-defined method always wins over roles.
.claude/skills/perl-moose/SKILL.md view on Meta::CPAN
parameter name => (isa => 'Str', required => 1);
role {
my $p = shift;
my $n = $p->name;
has $n => (is => 'rw', isa => 'Int', default => 0);
method "inc_$n" => sub { my $self = shift; $self->$n($self->$n + 1) };
};
package Game::Weapon;
use Moose;
use namespace::autoclean;
with 'Role::Counter' => { name => 'power' };
__PACKAGE__->meta->make_immutable;
# generates: power attribute + inc_power method
```
Use `method` (not `sub`) inside `role { }` block. Non-core â adds `MooseX::Role::Parameterized` dependency.
---
## Pattern 7 â Attribute Options Cheatsheet
.claude/skills/perl-moose/SKILL.md view on Meta::CPAN
- `coerce` only on your own subtypes, never on built-in type names (global side effects).
- `is => 'lazy'` requires a `_build_name` method or explicit `builder`.
---
## Pattern 8 â Native Traits Delegation
```perl
package TaskList;
use Moose;
use namespace::autoclean;
has tasks => (
traits => ['Array'],
is => 'ro',
isa => 'ArrayRef[Task]',
default => sub { [] },
handles => {
add_task => 'push',
next_task => 'shift',
all_tasks => 'elements',
.claude/skills/perl-moose/SKILL.md view on Meta::CPAN
Available native traits: `Array`, `Hash`, `Bool`, `String`, `Number`, `Counter`, `Code`. Each provides a set of generated methods. See `Moose::Meta::Attribute::Native::Trait::*` on CPAN.
---
## Pattern 9 â `handles` Delegation to Objects
```perl
package Website;
use Moose;
use namespace::autoclean;
has uri => (
is => 'ro',
isa => 'URI',
handles => [qw(host path)], # list form
# OR: handles => { hostname => 'host' } # rename form
# OR: handles => 'Role::URILike', # delegate interface from role
);
__PACKAGE__->meta->make_immutable;
# $site->host() calls $site->uri->host() internally
```
.claude/skills/perl-moose/SKILL.md view on Meta::CPAN
**Rules:** `before`/`after` cannot alter return value; `around` can. Always capture and forward `@_` correctly in `around`. Multiple modifiers from multiple roles stack in composition order.
---
## Pattern 11 â `augment` / `inner` (Inverted Inheritance)
```perl
package Report;
use Moose;
use namespace::autoclean;
sub render {
my $self = shift;
"<html>" . inner() . "</html>"; # inner() calls augment from child
}
__PACKAGE__->meta->make_immutable;
package PDFReport;
use Moose;
use namespace::autoclean;
extends 'Report';
augment 'render' => sub {
my $self = shift;
"<pdf>" . inner() . "</pdf>"; # chain further down if needed
};
__PACKAGE__->meta->make_immutable;
```
Use when the parent defines the *frame* and children fill in the *content*. Rare â only when the parent controls the wrapper structure.
.claude/skills/perl-moose/SKILL.md view on Meta::CPAN
**Rules:**
- Never define `sub new` â use `BUILDARGS`/`BUILD` instead.
- `BUILDARGS`: class method, runs before construction, returns hashref.
- `BUILD`: object method, runs after construction. Moose calls all `BUILD` in the hierarchy automatically.
- Never call `SUPER::BUILD` manually.
- For cleanup: use `DEMOLISH` (childâparent order), never override `DESTROY`.
---
## Pattern 13 â `make_immutable` + `namespace::autoclean`
```perl
package MyClass;
use Moose;
use namespace::autoclean; # remove imported keywords after compile
has name => (is => 'ro', required => 1);
__PACKAGE__->meta->make_immutable; # ALWAYS â massive perf gain on object creation
```
**Rules:**
- `namespace::autoclean` goes at the top (after `use Moose`), `make_immutable` at the bottom.
- After `make_immutable`: no more dynamic `add_attribute`, `add_role` etc.
- `namespace::autoclean` removes `has`, `with`, `extends` etc. from the symbol table â they won't accidentally become methods.
---
## Pattern 14 â Type Constraints
```perl
use Moose::Util::TypeConstraints;
subtype 'PositiveInt',
as 'Int',
( run in 1.853 second using v1.01-cache-2.11-cpan-39bf76dae61 )