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
Kenta Kobayashi
June 17, 2019
Technology
3.4k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Interfaces in Perl5 at The Perl Conference 2019 in Pittsburgh
Kenta Kobayashi
June 17, 2019
More Decks by Kenta Kobayashi
See All by Kenta Kobayashi
Perlの生きのこり - YAPC::Fukuoka 2025
kfly8
0
2.1k
プロジェクトの空気を読んで開発してくれるPerlのAIツールがほしい
kfly8
2
990
Perlの生きのこり - エンジニアがこの先生きのこるためのカンファレンス2025
kfly8
4
3.2k
Tシャツに書かれたコードを読む
kfly8
0
1.5k
Introduce Sub::Meta
kfly8
0
110
研修はイベントでなくコミュニティ作り
kfly8
0
2.3k
明日からできる新人のオンボーディングガイド
kfly8
0
910
メンター成長のためのふりかえり会
kfly8
0
1.4k
経験から効率よく学習する
kfly8
0
490
Other Decks in Technology
See All in Technology
壊して学ぶAWS CDK: そのcdk deployで消えるもの、残るもの
k_adachi_01
1
420
AIコード生成×サプライチェーン攻撃 — PHPが直面する“二重の信頼問題
shinyasaita
0
220
AIレビューはどこまで任せられるのか?自動化と人が背負うレビューの境界
sansantech
PRO
3
1.1k
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
15
110k
Kaggleで成長するために意識したこと
prgckwb
2
420
[2026-07-15] AI Ready なはずだったアーキテクチャと、見えてきた課題・次に目指す状態
wxyzzz
9
4k
プロダクト開発組織の現在地(Ver.2026/07) / product-organization
kaonavi
0
120
AmplifyHostingConstructからSSRフレームワークのためのホスティング設計を考察する/amplify-hosting-construct
fossamagna
1
240
インフラと開発の垣根を超えていき!〜元AWSインフラエンジニアがAWS開発で奮闘している話〜
hatahata021
3
300
シンガポールで登壇してきます
yama3133
0
250
タスクの複雑さでモデルを選ぶ ── Thompson Samplingで動かす“トークン/コスト最適化
satohy0323
0
570
世界、断片、モデル。そして理解
ardbeg1958
1
130
Featured
See All Featured
The Language of Interfaces
destraynor
162
27k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
400
BBQ
matthewcrist
89
10k
GraphQLとの向き合い方2022年版
quramy
50
15k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.1k
Utilizing Notion as your number one productivity tool
mfonobong
4
430
Chasing Engaging Ingredients in Design
codingconduct
0
240
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Mind Mapping
helmedeiros
PRO
1
280
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
420
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
350
Evolving SEO for Evolving Search Engines
ryanjones
0
240
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!