あるソフトウェアエンジニアの戯言

日々の開発やサーバ管理のなかで出てきたあれや、これや、あんなことや、こんなこと

この記事のキーワード:   Moose   perl

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 でロックされてしまうようだ。

[トラックバック] トラックバックPingURL : http://blog.d-pad.co.jp/sugi/dblog/ping.fcgi/30
言及リンクのないページからのトラックバックは拒否される仕様になっておりますのでご注意ください。
名前:
メールアドレス(任意):
参考URL(任意):

キーワードリスト

バックナンバー