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.3k
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
920
Perlの生きのこり - エンジニアがこの先生きのこるためのカンファレンス2025
kfly8
4
3.1k
Tシャツに書かれたコードを読む
kfly8
0
1.5k
Introduce Sub::Meta
kfly8
0
100
研修はイベントでなくコミュニティ作り
kfly8
0
2.3k
明日からできる新人のオンボーディングガイド
kfly8
0
900
メンター成長のためのふりかえり会
kfly8
0
1.4k
経験から効率よく学習する
kfly8
0
480
Other Decks in Technology
See All in Technology
Microsoft Build Keynoteふりかえり
tomokusaba
0
120
非定型業務をAI slackbotで自動化する ~ 社内要望を自動壁打ちするbotを作った ~/automating-ad-hoc-work-with-ai-slackbot
shibayu36
0
580
AIソロプレナー時代に2ヶ月で20人増員した事業創造会社の開発組織の話
miyatakoji
0
570
小さくはじめるSLI/SLO ~育てながら組織に定着させる実践知~ / Starting Small with SLI/SLOs: Building Adoption Through Continuous Growth
nari_ex
3
1.4k
Bucharest Tech Week 2026 - Reinventing testing practices in the AI era
edeandrea
PRO
1
140
2026.06.13_AI時代に事業会社が「SIer出身エンジニア」を求める理由 / Why Businesses Seek Engineers with a System Integrator Background in the AI Era
jumtech
0
1k
中期計画、2回作ってみた ~業務委託と正社員、両方の視点から~
demaecan
1
650
データサイエンスを価値につなげるプロジェクト設計 〜 DS一年目が現場で得た気づき 〜
ysd113
1
150
2026TECHFRESH畢業分享會 - Lightning Talk - 打造精準高效的 MCP 設計模式與測試實務
line_developers_tw
PRO
0
700
AmazonRoute 53ではじめてのドメイン取得!HTTPS化までの道のりを整理してみた
usanchuu
3
130
FinOps × AIエージェントで実現する コストインシデントの自動調査
oasis1994liveforever
0
110
日本 Fintech 未来予測レポート 2027〜2028年(オリジナル版)
8maki
0
1.3k
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
770
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
330
How to Ace a Technical Interview
jacobian
281
24k
Designing for humans not robots
tammielis
254
26k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
Site-Speed That Sticks
csswizardry
13
1.2k
HDC tutorial
michielstock
2
700
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Git: the NoSQL Database
bkeepers
PRO
432
67k
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!