Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Interfaces in Perl5 at The Perl Conference 2019...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Kenta Kobayashi
June 17, 2019
Technology
0
3.2k
Interfaces in Perl5 at The Perl Conference 2019 in Pittsburgh
Kenta Kobayashi
June 17, 2019
Tweet
Share
More Decks by Kenta Kobayashi
See All by Kenta Kobayashi
Perlの生きのこり - YAPC::Fukuoka 2025
kfly8
0
1.7k
プロジェクトの空気を読んで開発してくれるPerlのAIツールがほしい
kfly8
2
670
Perlの生きのこり - エンジニアがこの先生きのこるためのカンファレンス2025
kfly8
4
2.9k
Tシャツに書かれたコードを読む
kfly8
0
1.4k
Introduce Sub::Meta
kfly8
0
92
研修はイベントでなくコミュニティ作り
kfly8
0
2.1k
明日からできる新人のオンボーディングガイド
kfly8
0
870
メンター成長のためのふりかえり会
kfly8
0
1.4k
経験から効率よく学習する
kfly8
0
460
Other Decks in Technology
See All in Technology
モダンUIでフルサーバーレスなAIエージェントをAmplifyとCDKでサクッとデプロイしよう
minorun365
4
220
Agile Leadership Summit Keynote 2026
m_seki
1
670
Kiro IDEのドキュメントを全部読んだので地味だけどちょっと嬉しい機能を紹介する
khmoryz
0
210
OCI Database Management サービス詳細
oracle4engineer
PRO
1
7.4k
マネージャー視点で考えるプロダクトエンジニアの評価 / Evaluating Product Engineers from a Manager's Perspective
hiro_torii
0
190
コンテナセキュリティの最新事情 ~ 2026年版 ~
kyohmizu
6
1.9k
予期せぬコストの急増を障害のように扱う――「コスト版ポストモーテム」の導入とその後の改善
muziyoshiz
1
2.1k
コスト削減から「セキュリティと利便性」を担うプラットフォームへ
sansantech
PRO
3
1.6k
CDK対応したAWS DevOps Agentを試そう_20260201
masakiokuda
1
420
10Xにおける品質保証活動の全体像と改善 #no_more_wait_for_test
nihonbuson
PRO
2
330
StrandsとNeptuneを使ってナレッジグラフを構築する
yakumo
1
130
日本の85%が使う公共SaaSは、どう育ったのか
taketakekaho
1
240
Featured
See All Featured
Reality Check: Gamification 10 Years Later
codingconduct
0
2k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.6k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.4k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
470
Everyday Curiosity
cassininazir
0
130
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.3k
Optimizing for Happiness
mojombo
379
71k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
240
30 Presentation Tips
portentint
PRO
1
220
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.1k
SEO for Brand Visibility & Recognition
aleyda
0
4.2k
AI: The stuff that nobody shows you
jnunemaker
PRO
2
270
Transcript
Interfaces in Perl5 kobaken a.k.a @kfly8 The Perl Conference 2019
#TPCiP
me • kobaken a.k.a @kfly8 • leader Gotanda.pm • orgnize
YAPC::Tokyo 2019
None
None
None
None
None
None
None
None
I ❤ Perl
Interfaces in Perl5
DBI
my $dbh = DBI->connect(...); my $items = $dbh->selectrow_arrayref(…);
Unified Interface independent of datastore
Unified Interface provides values
Limitation makes value
Agenda 1.DEMO & Features 2.Goal 3.Example: TODO app 4.Internal 5.Performance
Function::Interface is Java-like interface
DEMO
Features of Function::Interface 1.Typed interface definition 2.Check at compile time
What is Goal ?
To maintain large Perl apps
Interface is good for large apps
1. Be easier to fix implementation
2. Stable dependencies
Goal • To maintain large apps. • Interface is good
for large apps 1. Easy to fix implementation 2. Stable Dependencies
Example: TODO app
Case: “Inheritance”
package TodoRepository; use parent qw(DBI); sub new { my $class
= shift; $class->connect(…); }
package TodoRepository; … sub select { my ($self, $user_id)
= @_; $self->selectall_arrayref( ‘SELECT * FROM todos WHERE user_id = ?’, $user_id ); }
package TodoApp; use TodoRepository; my $repo = TodoRepository->new;
package TodoApp; use TodoRepository; my $repo = TodoRepository->new(…); sub my_todo_list
{ my $self = shift; my $todos = $repo->select($self->user_id); return $self->render($todos); }
TodoApp TodoRepository DBI TODO table
TodoApp TodoRepository DBI TODO table
TodoApp TodoRepository DBI TODO table Unstable Dependencies
package TodoApp; use TodoRepository; my $repo = TodoRepository->new; sub evil_method
{ $repo->do(“ANY QUERY!!!!”); }
package TodoApp; use TodoRepository; my $repo = TodoRepository->new; sub evil_method
{ $repo->do(“ANY QUERY!!!!”); } Too many features
easy to test?
my $mock = mock TodoRepository => ( select => sub
{ … } ); my $app = TodoApp->new; test $app->my_todo_list;
my $mock = mock TodoRepository => ( select => sub
{ … } ); my $app = TodoApp->new; test $app->my_todo_list; messy to test
Problems of “Inheritance” case 1.Unstable dependencies 2.Too many features 3.messy
to test
“Role” case
package TodoRepositoryInterface; use Moo::Role; requires qw(select);
package TodoRepository; use Moo; with qw( TodoRepositoryInterface ); has dbh
=> ( isa => ‘DBI::db’ );
package TodoRepository; use Moo; with qw( TodoRepositoryInterface ); has dbh
=> ( isa => ‘DBI::db’ );
package TodoRepository; … sub select { my ($self, $user_id) =
@_; $self->dbh->selectall_arrayref( ‘SELECT * FROM todos WHERE user_id = ?’, $user_id ); }
package TodoApp; use Moo; has todo_repo => ( is =>
‘ro’, does => ‘TodoRepositoryInterface’ );
package TodoApp; … sub my_todo_list { my $self = shift;
my $repo = $self->todo_repo; my $todos = $repo->select($self->user_id); return $self->render($todos); }
TodoApp TodoRepository DBI TODO table TodoRepositoryInterface
TodoApp TodoRepository DBI TODO table TodoRepositoryInterface NOT!
TodoApp TodoRepository DBI TODO table TodoRepositoryInterface more stable
Problems of “Inheritance” case 1.Unstable dependencies 2.Too many features 3.messy
to test
package TodoApp; use Moo; has todo_repo => ( is =>
‘ro’, does => ‘TodoRepositoryInterface’ ); sub evil_method { $todo_repo->do(“ANY QUERY!!!!”); }
package TodoApp; use Moo; has todo_repo => ( is =>
‘ro’, does => ‘TodoRepositoryInterface’ ); sub evil_method { $todo_repo->do(“ANY QUERY!!!!”); }
package TodoApp; use Moo; has todo_repo => ( is =>
‘ro’, does => ‘TodoRepositoryInterface’ ); sub evil_method { $todo_repo->do(“ANY QUERY!!!!”); } Necessary and sufficient features
Problems of “Inheritance” case 1.Unstable dependencies 2.Too many features 3.messy
to test
easy to test?
package TestTodoRepository; use Moo; with qw( TodoRepositoryInterface ); sub select
{ … }
package TestTodoRepository; use Moo; with qw( TodoRepositoryInterface ); sub select
{ … } Be easier to test
Problems of “Inheritance” case 1.Unstable dependencies 2.Too many features 3.messy
to test
no problem at all?
package TodoRepositoryInterface; use Moo::Role; requires qw(select); sub surprised_method { ..
do anything }
package TodoRepositoryInterface; use Moo::Role; requires qw(select); sub surprised_method { ..
do anything } Implementation reusable
package TodoRepositoryInterface; use Moo::Role; requires qw(select);
select($id) ? select(id => $id) ? select({ id => $id
}) ?
select($id) # => arrayref of Todo ? # => iterator
of Todo ?
select($id) # => arrayref of Todo ? # => iterator
of Todo ? Ambiguous interface input / output
Problems of “Role” case 1.Implementation reusable 2.Ambiguous interface input /
output
“Function::Interface” case
package TodoRepositoryInterface; use Function::Interface; use TodoTypes; method select(UserID $user_id) :Return(ArrayRef[Todo]);
Problems of “Role” case 1.Implementation reusable 2.Ambiguous interface input /
output
package TodoRepositoryInterface; use Function::Interface; use TodoTypes; method select(UserID $user_id) :Return(ArrayRef[Todo]);
sub surprising_method { … do anything }
package TodoRepositoryInterface; use Function::Interface; use TodoTypes; method select(UserID $user_id) :Return(ArrayRef[Todo]);
sub surprising_method { … do anything }
Problems of “Role” case 1.Implementation reusable 2.Ambiguous interface input /
output
package TodoRepository; use TodoTypes; use Function::Interface::Impl qw( TodoRepositoryInterface ); has
dbh => ( … ); method select(UserID $user_id) :Return(ArrayRef[Todo]) { … }
package TodoApp; use Moo; use TodoTypes; has todo_repo => (
isa => ImplOf["TodoRepositoryInterface"], ); sub my_todo_list { … }
Looks Good!
Internal
requirements 1.function implementation 2.function interface 3.check if interface is implmented
4.interface type
1. function implementation
Function::Parameters • subroutine signatures • developed by MAUKE
use Function::Parameters; use Types::Standard -types; fun add(Int $a, Int $b)
{ return $a + $b }
my $info = Function::Parameters::info(\&add); $info->positional_required; # => Int $a, Int
$b
Function::Return • specify function return types • created by myself
sub add :Return(Int) { 3.14 } add(); # ERROR! Invalid
type
my $info = Function::Return::info(\&add); $info->types; # => Int
Appendix about Function::Return
sub multi :Return(Num, Str) { 3.14, ‘message' } my ($pi,
$msg) = multi();
sub multi :Return(Num, Str) { 3.14, ‘message' } my ($pi,
$msg) = multi(); my $count = multi(); # ERROR!
requirements 1.function implementation 2.function interface 3.check if interface is implemented
4.interface type
2. function interface
Function::Interface • Keyword::Simple • PPR
Deparse fun hello() :Return(Str);
sub BEGIN { Function::Interface::_register_info({ package => ‘HelloInterface', keyword => ‘fun',
subname => ‘message', params => [], return => [&Str()]} ); }
my $info = Function::Interface::info(“HelloInterface”); $info->functions; # => hello(Str $msg) :Return(Str)
requirements 1.function implementation 2.function interface 3.check if interface is implemented
4.interface type
3.check if interface is implemented
use Function::Interface::Impl qw( FooInterface BarInterface BazInterface );
F::Parameters#info F::Return#info F::Interface#info
F::Parameters#info F::Return#info F::Interface#info
requirements 1.function implementation 2.function interface 3.check if interface is implemented
4.interface type
use Function::Interface::Types; my $type = ImplOF[‘FooInterface’]; # Foo is implements
of FooInterface my $foo = Foo->new; $type->check($foo);
requirements 1.function implementation 2.function interface 3.check if interface is implemented
4.interface type
Performance
F::I::Impl runs at compile time
F::Return has `no_check` option
Let’s benchmark
F::P + F::R + F::I F::P + F::R no_check +
F::I F::P + F::R no_check F::P Case1 Case4 Case2 Case3
F::P + F::R + F::I F::P + F::R no_check +
F::I F::P + F::R no_check F::P 360653.77/s 1499189.22/s 1499189.22/s 1499189.22/s Case1 Case4 Case2 Case3
$BTF $BTF $BTF $BTF
Conclusion
Features of F::Interface 1.Typed interface definition 2.Check at compile time
Goal • To maintain large apps. • Interface is good
for large apps 1. Easy to fix implementation 2. Stable Dependencies
Internal • function implementation • Function::Parameters + Function:\:Return • function
interface • Keyword::Simple + PPR • compare meta infos at compile time
Performance • The same speed as using only F::Parameters •
Function::Interface::Impl runs at CHECK phase • Function::Return has `no_check` option
Questions?
Thank you!