Moose::Cookbook::Basics::Recipe1 - (古典的な)Point型の例
概要
package Point;
use Moose;
has 'x' => (isa => 'Int', is => 'rw', required => 1);
has 'y' => (isa => 'Int', is => 'rw', required => 1);
sub clear {
my $self = shift;
$self->x(0);
$self->y(0);
}
package Point3D;
use Moose;
extends 'Point';
has 'z' => (isa => 'Int', is => 'rw', required => 1);
after 'clear' => sub {
my $self = shift;
$self->z(0);
};
....
# hash or hashrefs are ok for the constructor
my $point1 = Point->new(x => 5, y => 7);
my $point2 = Point->new({x => 5, y => 7});
my $point3d = Point3D->new(x => 5, y => 42, z => -5);
解説
古典的な Point の例である。Perl 6 Apocalypse 12 や K&R C にも似たような例が載っている。
Perl 5 の他のクラスと同様、Mooseのクラスもパッケージとして定義する。 Mooseは "use Moose"を宣言した時点で "strict" 及び "warnings" を自動的に有効にする。
パッケージにMooseが読込まれると、'sugar'関数がエクスポートされる。これらは、Mooseのキーワードとして機能する。これらはperlのキーワードではないが、パッケージにエクスポートされた時点でそのように振る舞うように設計されている。
Moose は作成されたパッケージを自動的に Moose::Object のサブクラスとして定義するようになっている。 Moose::Objectクラスは属性(attribute)やその他の機能を果たすようなコンストラクタを提供する。詳しくは Moose::Object を参照のこと。
と、ここまで書いたけど、全部訳していると、時間がかかってしょうがないので、これ以降は、気がついたことや、やってみたことなどだけ、、、
method modifier
メソッドをサブクラスで変更したい場合は、 method modifierを使う。
例には after キーワードで
after 'clear' => sub {
my $self = shift;
$self->z(0);
};
なる例が出てくる。
これを、 override キーワードを使って
override 'clear' => sub {
my $self = shift;
super();
$self->z(0);
};
とやっても、全く同じになる。
ここで、疑問発生。
引数がsuper()関数にも全く同じものが渡っているのだが、perlの関数引数(@_)ってば、呼び出された側で書換え可能だったはず。
どうなってるのかと思って、
use Moose;
extends 'Point';
has 'z' => (isa => 'Int', is => 'rw', required => 1);
override 'clear' => sub {
my $self = shift;
$_[0] = 10;
super();
$self->z(0);
};
# hash or hashrefs are ok for the constructor
my $point1 = Point->new(x => 5, y => 7);
my $point2 = Point->new({x => 5, y => 7});
my $point3d = Point3D->new(x => 5, y => 42, z => -5);
$point3d->clear('a');
こうやってみた。
すると、
Modification of a read-only value attempted at test.pl line 26.
とのことで、関数への引数は read-only でロックされてしまうようだ。