Source profileQuality 82/100

affaan-m/ECC/docs/ja-JP/skills/perl-patterns/SKILL.md

perl-patterns

Review perl-patterns's use cases, installation, workflow, and original source instructions.

Source repository stars
234,327
Declared platforms
0
Static risk flags
1
Last source update
2026-07-27
Source checked
2026-07-28

Decision brief

What it does—and where it fits

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

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/perl-patterns"
    Safe inspection promptEditorial

    Inspect the Agent Skill "perl-patterns" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/docs/ja-JP/skills/perl-patterns/SKILL.md at commit 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

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

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

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

      仕組み

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

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

      コア原則

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

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

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

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

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

      Good: モダンなプリアンブル

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

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

    Permission review

    Static risk signals and limitations

    Reads files

    low · line 458

    The documentation asks the agent to read local files, directories, or repositories.

    | `open FH, "< $file"` | `open my $fh, '<:encoding(UTF-8)', $file` |

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score82/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars234,327SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    affaan-m/ECC
    Skill path
    docs/ja-JP/skills/perl-patterns/SKILL.md
    Commit
    4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    モダン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の実績あるモジュールを優先する。

    Alternatives

    Compare before choosing