PerlでMooとTypes::Standardを使ってオブジェクト指向プログラミングをする方法まとめ
Perlでオブジェクト指向プログラミングをする場合、Moo
というモジュールが便利なので紹介する。
似たようなモジュールにMoose
などがあるが、Moo
が軽量でかつ十分な機能を備えているのでおすすめ。
また、型をつけるのに便利なTypes::Standard
も解説する。
環境構築
以下のモジュールをインストールする。cpmを使う。
cpm install Moo Types::Standard
Mooの使い方
Mooの使い方は簡単。覚えるべきものはhas
とextends
くらい。
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
属性に文字列型Str
、age
属性に整数型Int
を指定していることがわかる。
Types::Standard
では、他にも様々な型が用意されている。
例えば、Bool
、ArrayRef
、HashRef
などがある。
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']);
};