2020年はどうなるかは置いておいて、2019年の最先端のPerl開発ボイラープレート - Qiitaを参考にする。
- Moo
 - strictures
 - Function::Parameters
 - Type::Tiny
 
あたりを使う。
最近、Mooseを使ってデザインパターンを実装してみてるのでこれらを使って、Chain of Responsibilityパターンをなんとなく書いてみた。ちなみに以下のJava実装が解説を含めて分かりやすいので、ポーティングするような形で書いている。
Java実装との最大の差はInterfaceとか抽象クラスという概念がp5-Moose/Mooにはないことなんだけど、Roleがハマる時はRoleを使って表現している(といってもそのまま書き写すんじゃなくてPerlっぽい書き方で書いてるつもり)。
Support.pm。Javaでは抽象クラスで書かれてたけど、今回はRoleを使った。
package Support;
use Moo::Role;
use strictures 2;
use namespace::clean;
use Function::Parameters;
use Types::Standard qw/Str Object/;
has 'name' => (
    is => 'ro',
    isa => Str,
);
has 'next' => (
    is => 'rw',
    isa => Object,
);
requires 'resolve';
method support($trouble) {
    if ( $self->resolve($trouble) ) {
        $self->done($trouble);
    } elsif ( $self->next ) {
        $self->next->support($trouble);
    } else {
        $self->fail($trouble);
    }
}
method done($trouble) {
    print $trouble->to_string . " is resolve by [" . $self->name . "].\n";
}
method fail($trouble) {
    print $trouble->to_string . " is cannot be resolved.\n";
}
1;
methodカッコイイ。ほんとはnextプロパティでSupportロールを実装しているクラスのインスタンス、ってのを指定したかったけど(Mooseだとできる)、Type::Standardにはそういうのなさそうなので(RoleNameっていうTypeならある)Objectを指定してる。
SpecialSupport.pmでは上記のRoleをwithして実装。
package SpecialSupport;
use Moo;
use strictures 2;
use namespace::clean;
use Function::Parameters;
use Types::Standard qw/Int/;
with 'Support';
has 'number' => (
    is => 'ro',
    isa => Int,
);
method resolve($trouble) {
    return $trouble->number == $self->number;
}
1;
methodカッコイイ(2度目)。
Data::Validatorでやってたような、メソッドの引数の型チェックをType::Tinyと組み合わせて「かっこよく」書けるかな?って思った。以下、実装の全部。