吉祥寺.pm #17 で話した内容です。吉祥寺.pm 楽しかったです! ちなむと吉祥寺.pmのフィードバックはこちらです。楽しかった。
弊社で吉祥寺pmのフィードバックがあり、懇親会はご飯が旨くて楽しいってフィードバックがされました。https://t.co/7rVLyAjFu2
— kobaken (@kfly8) 2019年3月8日
ビール🍺が飲みたくなりました。#kichijojipm
本題
Perlのインタフェース実装をしました。雰囲気はJavaとかのインタフェースです。 次のキャプチャにあるように、コンパイル時に色々教えてくれて嬉しいです。
使い方
まず、インタフェースの定義は次のようにします。
例えば、fun hello(Str $msg) :Return(Str);
と書けば、引数はStr $msg
、返り値の型はStr
な関数hello
を宣言します。
package IFoo { use Function::Interface; use Types::Standard -types; fun hello(Str $msg) :Return(Str); fun add(Int $a, Int $b) :Return(Int); }
次に、インタフェースの実装は次のようにします。 Function::ParametersとFunction::Returnを用いて関数の実装をします。
package Foo { use Function::Interface::Impl qw(IFoo); use Types::Standard -types; fun hello(Str $msg) :Return(Str) { return "HELLO $msg"; } fun add(Int $a, Int $b) :Return(Int) { return $a + $b; } }
そして、ImplOf['IFoo']
のようにインタフェースの型指定します。
実装に依存しなくなって、嬉しいですね。
package FooService { use Function::Interface::Types qw(ImplOf); use Function::Parameters; use Function::Return; use Mouse; use aliased 'IFoo'; fun greet(ImplOf[IFoo] $foo) :Return() { print $foo->hello; return; } } my $foo_service = FooService->new; my $foo = Foo->new; # implements of IFoo $foo_service->greet($foo);
奇妙ですが、面白いですね!
仕組み
簡単ですが、次のような感じです。
- Function::Interface は、Keyword::Simple + PPR で文法を拡張しています。Deparseすると、抽象関数のメタ情報を保存していることがわかります。
- Function::Interface::Impl は、保存したインタフェースのメタ情報と、Function::Parameters、Function::Returnを用いて取得できる実装のメタ情報を付き合わせて、エラー判定しています。
- ImplOf は、Type::Tinyでparameterizeして型を定義しています。
Perlの自由さが感じられて楽しいですね。機会があれば、詳解したいです。
さいごに
遊んでくれる人がいると嬉しいです。以上です!