この記事はPerl Advent Calendar 2018の2日目の記事です。
皆さん、PerlでOOPしてますか?
私は今年Perlに入門したのですが、Perlのオブジェクト指向はかなり独特だと感じました。
MouseやMooseを使って簡単に書くことはできますが、やはりそれでも他言語の構文との差はあるように思います。
そこで、Perlの柔軟な文法を活かしてclass構文を作ってみることにしました。
方針
- できるだけJavaっぽくする
- blessは裏側でやる
- クラス名をクォートで囲わなくてはいけない箇所を減らす
- 素のPerlよりも堅牢になる仕組みを組み込む
実装
https://github.com/yumlonne/p5-Class-JavaLike
突貫で作っていたためコード汚いです
現在実装できているのは以下の機能です
- class構文
- アクセス修飾子(public・protected・private)
- 変数宣言(
public var => @array
) - コンストラクタ
- メソッド
- 引数型チェック
- 単純な継承
使用例
use Class::JavaLike;
use Class::JavaLike::Classes;
use Types::Standard -types;
# classの定義
class Point2D => sub {
# 変数の定義
public var => qw(x y);
# コンストラクタ
public new => args[Int, Int] => returns[classes->Point2D] => constructor {
my ($self, $x, $y) = @_;
$self->x = $x;
$self->y = $y;
return $self;
};
# addメソッド
public add => args[classes->Point2D] => returns[classes->Point2D] => method {
my ($self, $that) = @_;
return classes->Point2D->new($self->x + $that->x, $self->y + $that->y);
};
# プライベートなnegateメソッド
private negate => args[] => returns[classes->Point2D] => method {
my $self = shift;
return classes->Point2D->new(-$self->x, -$self->y);
};
};
こんな感じでclassを定義できます。
裏側では、パッケージClass::JavaLike::Class::${ClassName}
にメソッド群を植え付けています。
このクラスは以下のように使えます。
# usage
my $p1 = classes->Point2D->new(10, 20);
my $p2 = classes->Point2D->new(22, 18);
my $res = $p1->add($p2);
say $res->x; # -> 32
say $res->y; # -> 38
classes->Point2D
は単に'Class::JavaLike::Class::Point2D'
という文字列を生成しています。
同様のことがclassof('Point2D')
でできますが、クォートが冗長だと思い、AUTOLOADを使ってクォート無しで指定できるようにしました。
また、継承ができるので、Point2Dを継承させてPoint3Dを作ることもできます。
class Point3D => extends Point2D => sub {
public var => 'z';
public new => args[Int ,Int ,Int] => returns[classes->Point3D] => constructor {
my ($self, $x, $y, $z) = @_;
$self->x = $x;
$self->y = $y;
$self->z = $z;
return $self;
};
public add => args[classes->Point3D] => returns[classes->Point3D] => method {
my ($self, $that) = @_;
return classes->Point3D->new($self->x + $that->x, $self->y + $that->y, $self->z + $that->z);
};
};
展望
戻り値の型チェックや再代入不能な変数(val
)の導入などなど、Perlでのプログラミングを堅牢にする仕組みを導入できそうですね!
まだまだ未完成なので、今後も改善していきます。
最後に
Perlの文法を使い、何ができるか考えるのがすごく面白かったです。
みなさんもやってみてはいかがでしょうか。
明日は omokawa_yasu さんです!お楽しみに!!