PerlのOOPの未来
吉祥寺.pm27 LT
自己紹介
https://gyazo.com/2c7b2fd541f235ace2a6c178695a5f9b
株式会社モバイルファクトリーでソフトウェアエンジニアをしています
きちぴーで発表するのは多分2回目
Perlの話をしにきました
突然ですが皆さん、Cor というものをご存知ですか?
PerlにおけるOOPの課題
コアには貧弱な機能しか備わっていない(blessでパッケージ名と紐付ける&@ISAを操作して継承できるくらい)
なのでクラスビルダーと呼ばれるOOPをサポートするモジュールを利用して書くことが多い
クラスビルダーも乱立していて選択が大変
TMTOWTDIもいいけど簡単にOOPが実現できる構文がほしい
Cor とは
Perlのオブジェクト指向構文のプロポーザル
将来的にPerlコアに入ることを目標にしている
Cor の現在
仕様についてある程度方向性が固まってきているらしく、ここに現状考えられている仕様がまとめられている issuesでは Cor のプロポーザルについての議論を行っている https://www.youtube.com/watch?v=kSZO-aJg4dM
CorがPerlコアに入ることは実際にありえるのか?
コアチームの何人かのメンバーはいい反応をしているし、仕様の決定に協力したりもしている
個人的にはプロトタイプのObject::Padのクオリティがあがればかなり期待できると思っている
Object::Pad について
inside-out objects ベースのクラスらしい
Perl 5.18 以降で利用できる
class, role, method構文のサポート
has $value でインスタンス変数を宣言、$self を介さずともインスタンス変数にアクセスできる
code:perl
use v5.34;
use Object::Pad;
role Movable {
requires move;
}
class Point does Movable {
has $x = 0;
has $y = 0;
method move($dx, $dy) {
$x += $dx;
$y += $dy;
}
}
my $point = Point->new();
use DDP +{ deparse => 1, use_prototypes => 0 };
p $point;
# Point {
# parents: Object::Pad::UNIVERSAL
# public methods (5):
# DOES, META, move, new
# Object::Pad::UNIVERSAL:
# BUILDARGS
# private methods (0)
# internals: [
# ]
# }
attribute で reader / write を自動生成したり必須のプロパティであることを指定したりする
code:perl
use v5.34;
use Object::Pad;
class Point {
has $x :param :reader; # :param = 必須プロパティ, :reader = getter生成
has $y :param :reader;
method move($dx, $dy) {
$x += $dx;
$y += $dy;
}
}
# my $point = Point->new(); # error
my $point = Point->new(x => 1, y => 2);
say $point->x; # 1
say $point->y; # 2
メタオブジェクトプロトコルも用意されている(Object::Pad::MOP)
code:perl
use v5.34;
use Test2::V0;
use Object::Pad;
class Point {
has $x :param :reader;
has $y :param :reader;
method move($dx, $dy) {
$x += $dx;
$y += $dy;
}
}
is Point::META->name, 'Point';
my @slots = Point::META->slots;
is \@slots, array {
item object { prop isa => 'Object::Pad::MOP::Slot' };
item object { prop isa => 'Object::Pad::MOP::Slot' };
};
like dies {
Point::META->add_method(do_something => sub {
my $self = shift;
say $self->x + $self->y;
});
}, qr/^Cannot add a new method to an already-sealed class at/;
done_testing;
ベンチマーク
コンストラクタ
code:txt
Benchmark: timing 10000000 iterations of class_inside_out, default, mouse, object_pad...
class_inside_out: 37 wallclock secs (37.56 usr + 0.00 sys = 37.56 CPU) @ 266240.68/s (n=10000000)
default: 9 wallclock secs ( 9.17 usr + 0.00 sys = 9.17 CPU) @ 1090512.54/s (n=10000000)
mouse: 9 wallclock secs ( 9.56 usr + 0.00 sys = 9.56 CPU) @ 1046025.10/s (n=10000000)
object_pad: 12 wallclock secs (12.58 usr + 0.00 sys = 12.58 CPU) @ 794912.56/s (n=10000000)
Rate class_inside_out object_pad mouse default
class_inside_out 266241/s -- -67% -75% -76%
object_pad 794913/s 199% -- -24% -27%
mouse 1046025/s 293% 32% -- -4%
default 1090513/s 310% 37% 4% --
reader
code:txt
Benchmark: timing 10000000 iterations of class_inside_out, default, mouse, object_pad...
class_inside_out: 3 wallclock secs ( 2.71 usr + 0.00 sys = 2.71 CPU) @ 3690036.90/s (n=10000000)
default: 2 wallclock secs ( 1.04 usr + 0.00 sys = 1.04 CPU) @ 9615384.62/s (n=10000000)
mouse: 1 wallclock secs ( 0.69 usr + 0.00 sys = 0.69 CPU) @ 14492753.62/s (n=10000000)
object_pad: 3 wallclock secs ( 2.03 usr + 0.00 sys = 2.03 CPU) @ 4926108.37/s (n=10000000)
Rate class_inside_out object_pad default mouse
class_inside_out 3690037/s -- -25% -62% -75%
object_pad 4926108/s 33% -- -49% -66%
default 9615385/s 161% 95% -- -34%
mouse 14492754/s 293% 194% 51% --
感想
全体的にPerlらしい構文になっていると感じた、has $value はイケてる
かなり Moose の影響を受けている
コンストラクタに渡す引数が名前付き引数
role やBUILD, BUILDARGSなどのフックポイント
型がほしい
Cor には型を指定する :isa attributeについての記述があったので将来的にできるようになるかも
型さえ指定できるようになったら個人では実用したい
実装が不思議なので詳しく調べたい
まとめ
Corというオブジェクト指向構文のプロポーザルがあって、かなり詳細なところまで仕様が決まっていっている
Object::PadというCorのプロトタイプ実装がある
将来use feature 'class'; でオブジェクト指向構文が使えるようになるかもしれない
Perlコアにオブジェクト指向構文が入ることが僕の願いです