Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Interfaces in Perl5 at The Perl Conference 2019 in Pittsburgh

Interfaces in Perl5 at The Perl Conference 2019 in Pittsburgh

Kenta Kobayashi

June 17, 2019
Tweet

More Decks by Kenta Kobayashi

Other Decks in Technology

Transcript

  1. DBI

  2. Goal • To maintain large apps. • Interface is good

    for large apps 1. Easy to fix implementation 2. Stable Dependencies
  3. package TodoRepository; … 
 sub select { my ($self, $user_id)

    = @_; $self->selectall_arrayref( ‘SELECT * FROM todos WHERE user_id = ?’, $user_id ); }
  4. 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); }
  5. my $mock = mock TodoRepository => ( select => sub

    { … } ); my $app = TodoApp->new; test $app->my_todo_list;
  6. my $mock = mock TodoRepository => ( select => sub

    { … } ); my $app = TodoApp->new; test $app->my_todo_list; messy to test
  7. package TodoRepository; … sub select { my ($self, $user_id) =

    @_; $self->dbh->selectall_arrayref( ‘SELECT * FROM todos WHERE user_id = ?’, $user_id ); }
  8. package TodoApp; use Moo; has todo_repo => ( is =>

    ‘ro’, does => ‘TodoRepositoryInterface’ );
  9. 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); }
  10. package TodoApp; use Moo; has todo_repo => ( is =>

    ‘ro’, does => ‘TodoRepositoryInterface’ );
 sub evil_method { $todo_repo->do(“ANY QUERY!!!!”); }
  11. package TodoApp; use Moo; has todo_repo => ( is =>

    ‘ro’, does => ‘TodoRepositoryInterface’ );
 sub evil_method { $todo_repo->do(“ANY QUERY!!!!”); }
  12. package TodoApp; use Moo; has todo_repo => ( is =>

    ‘ro’, does => ‘TodoRepositoryInterface’ );
 sub evil_method { $todo_repo->do(“ANY QUERY!!!!”); } Necessary and sufficient features
  13. select($id) # => arrayref of Todo ? # => iterator

    of Todo ? Ambiguous interface input / output
  14. package TodoRepository; use TodoTypes; use Function::Interface::Impl qw( TodoRepositoryInterface ); has

    dbh => ( … ); method select(UserID $user_id) :Return(ArrayRef[Todo]) { … }
  15. package TodoApp; use Moo; use TodoTypes; has todo_repo => (

    isa => ImplOf["TodoRepositoryInterface"], ); sub my_todo_list { … }
  16. sub multi :Return(Num, Str) { 3.14, ‘message' } my ($pi,

    $msg) = multi(); my $count = multi(); # ERROR!
  17. 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
  18. 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
  19. Goal • To maintain large apps. • Interface is good

    for large apps 1. Easy to fix implementation 2. Stable Dependencies
  20. Internal • function implementation • Function::Parameters + Function:\:Return • function

    interface • Keyword::Simple + PPR • compare meta infos at compile time
  21. Performance • The same speed as using only F::Parameters •

    Function::Interface::Impl runs at CHECK phase • Function::Return has `no_check` option