PerlでMooとTypes::Standardを使ってオブジェクト指向プログラミングをする方法まとめ

Perlでオブジェクト指向プログラミングをする場合、Mooというモジュールが便利なので紹介する。

似たようなモジュールにMooseなどがあるが、Mooが軽量でかつ十分な機能を備えているのでおすすめ。

また、型をつけるのに便利なTypes::Standardも解説する。

環境構築

以下のモジュールをインストールする。cpmを使う。

cpm install Moo Types::Standard

Mooの使い方

Mooの使い方は簡単。覚えるべきものはhasextendsくらい。


package Person { use v5.40; use Moo; use utf8; # ro 読み取り専用 required 必須 has 'name' => (is => 'ro', required => 1); # rw 読み書き可能 default デフォルト値 has 'age' => (is => 'rw', default => sub { 20 }); sub greet($self) { return "Hello, my name is " . $self->name . " and I am " . $self->age . " years old."; } }; my $person = Person->new(name => "Alice"); print $person->greet(); # Hello, my name is Alice and I am 20 $person->age(25); # 年齢を更新 print $person->greet(); # Hello, my name is Alice and I am 25

上記のコードで、Perlでも直感的にオブジェクト指向プログラミングができることがわかる。

次にextedsを使って継承する方法を解説する。

package Animal {
    use v5.40;
    use Moo;
    use utf8;

    has 'species' => (is => 'ro', required => 1);

    sub speak($self) {
        return "The " . $self->species . " makes a sound.";
    }
};

package Dog {
    use v5.40;
    use Moo;
    use utf8;
    extends 'Animal'; # Animalを継承

    has 'name' => (is => 'ro', required => 1);

    # speakメソッドをオーバーライド
    sub speak($self) {
        return $self->name . " says Woof!";
    }
};

my $dog = Dog->new(species => "Dog", name => "Buddy");
print $dog->speak(); # Buddy says Woof!

上記のコードで、Animalクラスを継承してDogクラスを作成し、speakメソッドをオーバーライドしていることがわかる。

もし継承元のメソッドを使いたい場合は、SUPER::を使えばよい。 上記の例であれば、以下のようにする。

    sub speak($self) {
        return $self->name . " says Woof! Also, " . $self->SUPER::speak();
    }

Types::Standardの使い方

Types::Standardは型をつけるのに便利なモジュール。

これも説明するよりもコード例を見たほうがわかりやすい。

package Person {
    use v5.40;
    use Moo;
    use utf8;
    use Types::Standard qw(Str Int);

    # `isa`で型を指定できる Str
    has 'name' => (is => 'ro', required => 1, isa => Str);

    # `isa`で型を指定できる Int
    has 'age' => (is => 'rw', default => sub { 20 }, isa => Int);

    sub greet($self) {
        return "Hello, my name is " . $self->name . " and I am " . $self->age . " years old.";
    }
};

上記のコードで、name属性に文字列型Strage属性に整数型Intを指定していることがわかる。

Types::Standardでは、他にも様々な型が用意されている。 例えば、BoolArrayRefHashRefなどがある。

use Types::Standard qw(Bool ArrayRef HashRef);

他のクラスのインスタンスを型として指定したい場合は、InstanceOfを使う。

use Types::Standard qw(InstanceOf);
use AnotherClass;

package MyClass {
    use v5.40;
    use Moo;
    use utf8;
    use Types::Standard qw(InstanceOf);
    use AnotherClass;

    # AnotherClassのインスタンスであることを保証
    has 'another' => (is => 'ro', isa => InstanceOf['AnotherClass']);
};

参考文献