Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

prototype大全 / YAPC::Kyoto 2023

prototype大全 / YAPC::Kyoto 2023

サンプルコードはGitHubで公開しています
https://github.com/utgwkk/yapc-kyoto-2023-prototype

utagawa kiki

March 19, 2023
Tweet

More Decks by utagawa kiki

Other Decks in Programming

Transcript

  1. 突然ですがこちらのコードをご覧ください (2) push @arr, "new value"; # なんでこれでpushできるの? map {

    $_ + 2 } @arr; # { } の中は何? try { everything() } catch { up() }; # try-catchだ!!1 →prototypeが関係している
  2. 今日の目標 (1) push @arr, "new value"; map { $_ +

    2 } @arr; try { everything() } catch { up() }; これらの裏で起こっていることからprototypeを読み解く
  3. prototypeの書き方 (1) sub name (prototype) { ... } サブルーチン定義の後ろに括弧で書く sub

    name :prototype(prototype) { ... } attributeを使うこともできる (subroutine signaturesと衝突しない)
  4. prototypeの書き方 (2) sub name (prototype) { ... } ← この発表ではこっちを使う

    サブルーチン定義の後ろに括弧で書く sub name :prototype(prototype) { ... } attributeを使うこともできる (subroutine signaturesと衝突しない)
  5. prototypeの例 sub foo ($) { } sub bar ($;$@) {

    } sub mymap (&@) { } sub zip (\@\@) { } sub foo () { 1 }
  6. prototypeの読み方 (再掲) sub foo ($) { } # 括弧の中に記号を書く sub

    bar ($;$@) { } # ; 以降は省略可能 sub mymap (&@) { } # &はサブルーチン、@はリスト sub zip (\@\@) { } # リストをリファレンスとして受ける sub foo () { 1 } # 定数をreturnなしで返する
  7. prototypeに書けるもの だいたいなんでも書けてすごい だいたいなんでも書けるけどwarningされる sub f (hello!!1) { } # prototypeは

    hello!!1 sub g (こんにちは) { } # prototypeは こんにちは なんでだいたいなんでも書けるのかは不明 (知ってたら教えてください)
  8. Try::Tinyのコードを読んでいく (まとめ) try { } catch { } finally {

    }; try(sub { }, catch(sub { }, finally(sub { }))); 単なるサブルーチン呼び出し式なので、ブロックの後ろに ; が必要 ブロックではなく無名サブルーチンなのでreturnしても関数全体を抜けない (罠)
  9. 定数展開 sub a1 () { "aaa" } say a1 .

    "bbb"; コンパイル時に say "aaabbb" に展開される use constantしたときと似たような効能が得られる sub a2 { "aaa" } だと展開されない https://perldoc.perl.org/perlsub#Constant-Functions
  10. 身近に潜むprototype採用事例 (Test2::V0) is $obj, object { prop isa => 'Foo';

    call meth => 'blah'; }; $obj の性質を宣言的にテストできる ちなみにTest::Deepだと↓のように書ける cmp_deeply $obj, isa('Foo') & methods(meth => 'blah);
  11. 身近に潜むprototype採用事例 (Scope::Guard) my $g = guard { }; 変数 $g

    のスコープが終わったらブロックに渡した処理が呼ばれる これも無名サブルーチン スコープが終わったらDESTROYメソッドが呼ばれる 最近のPerlだとdeferがある (experimental)
  12. 身近に潜むprototype採用事例 (List::MoreUtils) (1) zip6 @xs, @ys, @zs; 6はPerl6 (現Raku) の6

    別名zip_unflatten [$xs[0], $ys[0], $zs[0]], [$xs[1], $ys[1], $zs[1]], ... のリストを返す
  13. 身近に潜むprototype採用事例 (List::MoreUtils) (2) ところで say @xs, @ys, @zs ってやったらリストが平坦になるのでは? zip6

    @xs, @ys, @zs では各リストはリファレンスとして渡されている リファレンスなら平坦になることはない % perl -E '@xs = (1, 2); @ys = (3, 4); @zs = (5, 6); say @xs, @ys, @zs' 123456
  14. 身近に潜むprototype採用事例 (List::MoreUtils) (3) sub zip6 (\@\@;\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\ @\@\@\@\@) \@ が32個!! 一番好きなprototypeです

    リストを33個渡すとコンパイルエラーになる (無限に渡せない) https://metacpan.org/release/REHSACK/List-MoreUtils-0.430/source/lib/List/More Utils/PP.pm#L520
  15. 身近に潜むprototype採用事例 (List::MoreUtils) (5) % carmel exec perl 02-list-moreutils-zip6.pl Too many

    arguments for List::MoreUtils::XS::zip6 at 02-list-moreutils-zip6.pl line 16, near ")" Execution of 02-list-moreutils-zip6.pl aborted due to compilation errors.
  16. おさらい 読めるようになりましたね? sub foo ($) { } sub bar ($;$@)

    { } sub mymap (&@) { } sub zip (\@\@) { } sub foo () { 1 }
  17. 参考文献 • https://perldoc.perl.org/perlsub • https://perldoc.jp/docs/perl/5.36.0/perlsub.pod#Prototypes • https://metacpan.org/pod/Try::Tiny • https://papix.hatenablog.com/entry/2019/12/02/170611 •

    https://metacpan.org/pod/Test2::V0 • https://metacpan.org/pod/List::MoreUtils • https://metacpan.org/pod/Scope::Guard • https://perldoc.perl.org/functions/prototype