affaan-m/ECC

perl-patterns

堅牢でメンテナブルなPerlアプリケーションを構築するためのModern Perl 5.36+のイディオム、ベストプラクティス、規約。

82CollectingReads files
See how to use itView GitHub source
npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/perl-patterns"
Automated source guide

Source checked Jul 28, 2026·Refresh due Oct 26, 2026

Reorganized from the pinned upstream SKILL.md

Turn perl-patterns's source instructions into a guide you can follow

According to the pinned SKILL.md from affaan-m/ECC: 堅牢でメンテナブルなアプリケーションを構築するためのイディオマティックなPerl 5.36+パターンとベストプラクティス。

npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/perl-patterns"
Check the pinned source

Best fit

  • 堅牢でメンテナブルなPerlアプリケーションを構築するためのModern Perl 5.36+のイディオム、ベストプラクティス、規約。

Bring this context

  • A concrete task that matches the documented purpose of perl-patterns.
  • The files, examples, or context the task depends on.
  • Your constraints, target environment, and definition of done.

Expected outputs

  • A result that follows the pinned perl-patterns instructions.
  • A concise record of assumptions, inputs used, and unresolved questions.
  • A final check against the source workflow and relevant permission signals.

Key source sections

Read perl-patterns through these 5 source sections

Sections are extracted automatically from the pinned SKILL.md and link back to the source.

01

アクティベートするタイミング

新しいPerlコードまたはモジュールを書くとき

SKILL.md · アクティベートするタイミング
新しいPerlコードまたはモジュールを書くときイディオム準拠のためにPerlコードをレビューするときレガシーPerlをモダンな標準にリファクタリングするとき
02

仕組み

これらのパターンをModern Perl 5.36+のデフォルトへのバイアスとして適用する: シグネチャ、明示的なモジュール、集中的なエラー処理、テスト可能な境界。以下の例は出発点としてコピーし、目の前の実際のアプリ、依存スタック、デプロイモデルに合わせて締め付けることを意図している。

SKILL.md · 仕組み
これらのパターンをModern Perl 5.36+のデフォルトへのバイアスとして適用する: シグネチャ、明示的なモジュール、集中的なエラー処理、テスト可能な境界。以下の例は出発点としてコピーし、目の前の実際のアプリ、依存スタック、デプロイモデルに合わせて締め付けることを意図している。
03

コア原則

単一のuse v5.36が古い定型文を置き換え、strict、warnings、サブルーチンシグネチャを有効化する。

SKILL.md · コア原則
単一のuse v5.36が古い定型文を置き換え、strict、warnings、サブルーチンシグネチャを有効化する。
04

1. v5.36プラグマの使用

単一のuse v5.36が古い定型文を置き換え、strict、warnings、サブルーチンシグネチャを有効化する。

SKILL.md · 1. v5.36プラグマの使用
単一のuse v5.36が古い定型文を置き換え、strict、warnings、サブルーチンシグネチャを有効化する。

SkillSignal prompt templates

Provide the task, context, and acceptance criteria

These prompts were written by SkillSignal from the source structure; they are not upstream text.

Task-start prompt

Confirm source fit, inputs, and outputs before acting.

Use perl-patterns to help me with: [specific task]. Context: [files, data, or background]. Constraints: [environment, scope, and prohibited actions]. Before acting, check the pinned SKILL.md and explain which sections apply, what inputs are still missing, and what you will deliver.

Source-guided execution

Make the Agent explicitly follow the key extracted sections.

Apply the pinned perl-patterns source to [task]. Pay particular attention to these source sections: “アクティベートするタイミング”, “仕組み”, “コア原則”, “1. v5.36プラグマの使用”, “Good: モダンなプリアンブル”. Preserve the important decision at each step. Mark facts not covered by the source as “needs confirmation” instead of inventing them. Then verify the result against my acceptance criteria: [criteria].

Result-review prompt

Check omissions, permissions, and source drift before delivery.

Review the current perl-patterns result: (1) does it satisfy the original task; (2) were any applicable steps or limits in the pinned SKILL.md missed; (3) did it perform any unauthorized file, command, network, or data action; and (4) which conclusions remain unverified? List issues first, then fix only what the source or user authorization supports.

Output checklist

Verify each item before delivery

The task matches the purpose documented in the SKILL.md.

The source section “アクティベートするタイミング” has been checked.

The source section “仕組み” has been checked.

The source section “コア原則” has been checked.

The source section “1. v5.36プラグマの使用” has been checked.

Inputs, constraints, and acceptance criteria are explicit.

Unverified facts, compatibility, and outcome claims are clearly marked.

Any file, command, network, or data action has been reviewed.

Choose a different workflow

When another Skill is the better fit

FAQ

What does perl-patterns do?

堅牢でメンテナブルなアプリケーションを構築するためのイディオマティックなPerl 5.36+パターンとベストプラクティス。

How do I start using perl-patterns?

The catalog detected this source-specific install command: npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/perl-patterns". Inspect the command and pinned source before running it.

Which Agent platforms does it declare?

No dedicated Agent platform is declared in the pinned source record.

Repository stars
234,327
Repository forks
35,711
Quality
82/100
Source repository last pushed

Quality breakdown

Based on traceable docs and repository signals; stars are not treated as quality.

82/100
Documentation26/30
Specificity14/25
Maintenance20/20
Trust signals22/25

Compare before choosing

Related Agent Skills and source variants

These links are selected from shared tasks, functions, stacks, platforms, and same-name variants. Compare the source owner, documentation, permissions, and maintenance signals.

perl-patterns by affaan-m

Modern Perl 5.36+ idioms, best practices, and conventions for building robust, maintainable Perl applications.

perl-patterns by affaan-m

现代 Perl 5.36+ 的惯用法、最佳实践和约定,用于构建稳健、可维护的 Perl 应用程序。

ab-testing by coreyhaines31

When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

churn-prevention by coreyhaines31

When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o

design-intelligence by event4u-app

Grounded design brief from the adopted corpus — style, WCAG-checked color tokens, typography, layout pattern, anti-patterns. Use on ui-design-brief or any which-style/palette/font/chart decision.

View original Skill.mdThis page is parsed directly from the repository SKILL.md without editorial rewriting. Collected: Jul 28, 2026 · about 1 min

モダンPerl開発パターン

堅牢でメンテナブルなアプリケーションを構築するためのイディオマティックなPerl 5.36+パターンとベストプラクティス。

アクティベートするタイミング

  • 新しいPerlコードまたはモジュールを書くとき
  • イディオム準拠のためにPerlコードをレビューするとき
  • レガシーPerlをモダンな標準にリファクタリングするとき
  • PerlモジュールのアーキテクチャをDesignするとき
  • 5.36以前のコードをモダンなPerlに移行するとき

仕組み

これらのパターンをModern Perl 5.36+のデフォルトへのバイアスとして適用する: シグネチャ、明示的なモジュール、集中的なエラー処理、テスト可能な境界。以下の例は出発点としてコピーし、目の前の実際のアプリ、依存スタック、デプロイモデルに合わせて締め付けることを意図している。

コア原則

1. v5.36プラグマの使用

単一のuse v5.36が古い定型文を置き換え、strict、warnings、サブルーチンシグネチャを有効化する。

# Good: モダンなプリアンブル
use v5.36;

sub greet($name) {
    say "Hello, $name!";
}

# Bad: レガシーな定型文
use strict;
use warnings;
use feature 'say', 'signatures';
no warnings 'experimental::signatures';

sub greet {
    my ($name) = @_;
    say "Hello, $name!";
}

2. サブルーチンシグネチャ

明確さと自動アリティチェックのためにシグネチャを使用する。

use v5.36;

# Good: デフォルト値付きシグネチャ
sub connect_db($host, $port = 5432, $timeout = 30) {
    # $hostは必須、その他はデフォルトあり
    return DBI->connect("dbi:Pg:host=$host;port=$port", undef, undef, {
        RaiseError => 1,
        PrintError => 0,
    });
}

# Good: 可変引数のためのスラーピーパラメータ
sub log_message($level, @details) {
    say "[$level] " . join(' ', @details);
}

# Bad: 手動引数アンパック
sub connect_db {
    my ($host, $port, $timeout) = @_;
    $port    //= 5432;
    $timeout //= 30;
    # ...
}

3. コンテキスト感度

スカラーvsリストコンテキストを理解する — Perlのコアコンセプト。

use v5.36;

my @items = (1, 2, 3, 4, 5);

my @copy  = @items;            # リストコンテキスト: すべての要素
my $count = @items;            # スカラーコンテキスト: カウント (5)
say "Items: " . scalar @items; # スカラーコンテキストを強制

4. 後置逆参照

ネストされた構造で読みやすさのために後置逆参照構文を使用する。

use v5.36;

my $data = {
    users => [
        { name => 'Alice', roles => ['admin', 'user'] },
        { name => 'Bob',   roles => ['user'] },
    ],
};

# Good: 後置逆参照
my @users = $data->{users}->@*;
my @roles = $data->{users}[0]{roles}->@*;
my %first = $data->{users}[0]->%*;

# Bad: 前置逆参照(チェーンで読みにくい)
my @users = @{ $data->{users} };
my @roles = @{ $data->{users}[0]{roles} };

5. isa演算子(5.32+)

中置型チェック — blessed($o) && $o->isa('X')を置き換える。

use v5.36;
if ($obj isa 'My::Class') { $obj->do_something }

エラー処理

eval/dieパターン

use v5.36;

sub parse_config($path) {
    my $content = eval { path($path)->slurp_utf8 };
    die "Config error: $@" if $@;
    return decode_json($content);
}

Try::Tiny(信頼性の高い例外処理)

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;
}

ネイティブtry/catch(5.40+)

use v5.40;

sub divide($x, $y) {
    try {
        die "Division by zero" if $y == 0;
        return $x / $y;
    }
    catch ($e) {
        warn "Error: $e";
        return;
    }
}

MooによるモダンOO

軽量でモダンなOOにはMooを優先する。メタプロトコルが必要な場合のみMooseを使用する。

# Good: Mooクラス
package User;
use Moo;
use Types::Standard qw(Str Int ArrayRef);
use namespace::autoclean;

has name  => (is => 'ro', isa => Str, required => 1);
has email => (is => 'ro', isa => Str, required => 1);
has age   => (is => 'ro', isa => Int, default  => sub { 0 });
has roles => (is => 'ro', isa => ArrayRef[Str], default => sub { [] });

sub is_admin($self) {
    return grep { $_ eq 'admin' } $self->roles->@*;
}

sub greet($self) {
    return "Hello, I'm " . $self->name;
}

1;

# 使用法
my $user = User->new(
    name  => 'Alice',
    email => 'alice@example.com',
    roles => ['admin', 'user'],
);

# Bad: ブレスされたhashref(バリデーションなし、アクセサなし)
package User;
sub new {
    my ($class, %args) = @_;
    return bless \%args, $class;
}
sub name { return $_[0]->{name} }
1;

Mooロール

package Role::Serializable;
use Moo::Role;
use JSON::MaybeXS qw(encode_json);
requires 'TO_HASH';
sub to_json($self) { encode_json($self->TO_HASH) }
1;

package User;
use Moo;
with 'Role::Serializable';
has name  => (is => 'ro', required => 1);
has email => (is => 'ro', required => 1);
sub TO_HASH($self) { { name => $self->name, email => $self->email } }
1;

ネイティブclassキーワード(5.38+、Corinna)

use v5.38;
use feature 'class';
no warnings 'experimental::class';

class Point {
    field $x :param;
    field $y :param;
    method magnitude() { sqrt($x**2 + $y**2) }
}

my $p = Point->new(x => 3, y => 4);
say $p->magnitude;  # 5

正規表現

名前付きキャプチャと/xフラグ

use v5.36;

# Good: 読みやすさのための/xを使った名前付きキャプチャ
my $log_re = qr{
    ^ (?<timestamp> \d{4}-\d{2}-\d{2} \s \d{2}:\d{2}:\d{2} )
    \s+ \[ (?<level> \w+ ) \]
    \s+ (?<message> .+ ) $
}x;

if ($line =~ $log_re) {
    say "Time: $+{timestamp}, Level: $+{level}";
    say "Message: $+{message}";
}

# Bad: 位置キャプチャ(メンテが難しい)
if ($line =~ /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\s+\[(\w+)\]\s+(.+)$/) {
    say "Time: $1, Level: $2";
}

プリコンパイルパターン

use v5.36;

# Good: 1回コンパイル、複数回使用
my $email_re = qr/^[A-Za-z0-9._%+-]+\@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;

sub validate_emails(@emails) {
    return grep { $_ =~ $email_re } @emails;
}

データ構造

リファレンスと安全な深いアクセス

use v5.36;

# ハッシュと配列リファレンス
my $config = {
    database => {
        host => 'localhost',
        port => 5432,
        options => ['utf8', 'sslmode=require'],
    },
};

# 安全な深いアクセス(どのレベルが欠落してもundefを返す)
my $port = $config->{database}{port};           # 5432
my $missing = $config->{cache}{host};           # undef、エラーなし

# ハッシュスライス
my %subset;
@subset{qw(host port)} = @{$config->{database}}{qw(host port)};

# 配列スライス
my @first_two = $config->{database}{options}->@[0, 1];

# 複数変数のforループ(5.36で実験的、5.40で安定)
use feature 'for_list';
no warnings 'experimental::for_list';
for my ($key, $val) (%$config) {
    say "$key => $val";
}

ファイルI/O

3引数open

use v5.36;

# Good: autodieを使った3引数open(コアモジュール、'or die'を排除)
use autodie;

sub read_file($path) {
    open my $fh, '<:encoding(UTF-8)', $path;
    local $/;
    my $content = <$fh>;
    close $fh;
    return $content;
}

# Bad: 2引数open(シェルインジェクションリスク、perl-securityを参照)
open FH, $path;            # 絶対にしない
open FH, "< $path";        # まだ悪い — モード文字列のユーザーデータ

ファイル操作のPath::Tiny

use v5.36;
use Path::Tiny;

my $file = path('config', 'app.json');
my $content = $file->slurp_utf8;
$file->spew_utf8($new_content);

# ディレクトリを反復
for my $child (path('src')->children(qr/\.pl$/)) {
    say $child->basename;
}

モジュール構成

標準プロジェクトレイアウト

MyApp/
├── lib/
│   └── MyApp/
│       ├── App.pm           # メインモジュール
│       ├── Config.pm        # 設定
│       ├── DB.pm            # データベース層
│       └── Util.pm          # ユーティリティ
├── bin/
│   └── myapp                # エントリーポイントスクリプト
├── t/
│   ├── 00-load.t            # コンパイルテスト
│   ├── unit/                # ユニットテスト
│   └── integration/         # インテグレーションテスト
├── cpanfile                 # 依存関係
├── Makefile.PL              # ビルドシステム
└── .perlcriticrc            # リンティング設定

エクスポーターパターン

package MyApp::Util;
use v5.36;
use Exporter 'import';

our @EXPORT_OK   = qw(trim);
our %EXPORT_TAGS = (all => \@EXPORT_OK);

sub trim($str) { $str =~ s/^\s+|\s+$//gr }

1;

ツーリング

perltidy設定(.perltidyrc)

-i=4        # 4スペースインデント
-l=100      # 100文字行長
-ci=4       # 継続インデント
-ce         # cuddled else
-bar        # 同じ行に開き括弧
-nolq       # 長い引用文字列のアウトデントをしない

perlcritic設定(.perlcriticrc)

severity = 3
theme = core + pbp + security

[InputOutput::RequireCheckedSyscalls]
functions = :builtins
exclude_functions = say print

[Subroutines::ProhibitExplicitReturnUndef]
severity = 4

[ValuesAndExpressions::ProhibitMagicNumbers]
allowed_values = 0 1 2 -1

依存関係管理(cpanfile + carton)

cpanm App::cpanminus Carton   # ツールをインストール
carton install                 # cpanfileから依存関係をインストール
carton exec -- perl bin/myapp  # ローカル依存関係で実行
# cpanfile
requires 'Moo', '>= 2.005';
requires 'Path::Tiny';
requires 'JSON::MaybeXS';
requires 'Try::Tiny';

on test => sub {
    requires 'Test2::V0';
    requires 'Test::MockModule';
};

クイックリファレンス: モダンPerlイディオム

レガシーパターンモダンな置き換え
use strict; use warnings;use v5.36;
my ($x, $y) = @_;sub foo($x, $y) { ... }
@{ $ref }$ref->@*
%{ $ref }$ref->%*
open FH, "< $file"open my $fh, '<:encoding(UTF-8)', $file
blessed hashref型付きのMooクラス
$1, $2, $3$+{name}(名前付きキャプチャ)
eval { }; if ($@)Try::Tinyまたはネイティブtry/catch(5.40+)
BEGIN { require Exporter; }use Exporter 'import';
手動ファイル操作Path::Tiny
blessed($o) && $o->isa('X')$o isa 'X'(5.32+)
builtin::true / falseuse builtin 'true', 'false';(5.36+、実験的)

アンチパターン

# 1. 2引数open(セキュリティリスク)
open FH, $filename;                     # 絶対にしない

# 2. 間接オブジェクト構文(あいまいな解析)
my $obj = new Foo(bar => 1);            # Bad
my $obj = Foo->new(bar => 1);           # Good

# 3. $_への過度の依存
map { process($_) } grep { validate($_) } @items;  # 追うのが難しい
my @valid = grep { validate($_) } @items;           # より良い: 分割する
my @results = map { process($_) } @valid;

# 4. strictリファレンスの無効化
no strict 'refs';                        # ほぼ常に間違い
${"My::Package::$var"} = $value;         # 代わりにhashを使用

# 5. グローバル変数を設定として使用
our $TIMEOUT = 30;                       # Bad: 可変グローバル
use constant TIMEOUT => 30;              # Better: 定数
# Best: デフォルト付きのMoo属性

# 6. モジュールロードのための文字列eval
eval "require $module";                  # Bad: コードインジェクションリスク
eval "use $module";                      # Bad
use Module::Runtime 'require_module';    # Good: 安全なモジュールロード
require_module($module);

忘れないこと: モダンなPerlはクリーン、読みやすく、安全である。use v5.36に定型文を処理させ、オブジェクトにはMooを使用し、手作りのソリューションよりCPANの実績あるモジュールを優先する。

Source repo
affaan-m/ECC
Skill path
docs/ja-JP/skills/perl-patterns/SKILL.md
Commit SHA
4e973d3eaf92
Repository license
MIT
Data collected