$30 off During Our Annual Pro Sale. View Details »

10年でどう変わった? はてなブックマークでのPerlの使い方

10年でどう変わった? はてなブックマークでのPerlの使い方

2019-11-03 YAPC::Nagoya::Tiny 2019
https://yapcjapan.connpass.com/event/146727/

INA Lintaro

November 03, 2019
Tweet

More Decks by INA Lintaro

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ ໊લ ɹ ͍ ͳ ҏಸ ɹ ɹ ΓΜͨΖ͏ ྛଠ࿠

    ɹ (id:tarao @oarat) 2008-08 ͸ͯͳΠϯλʔϯ (ϒοΫϚʔΫνʔϜ) 2008-10 ͸ͯͳΞϧόΠτ (ϒοΫϚʔΫνʔϜ) 2010-04 ೔ຊֶज़ৼڵձ ಛผݚڀһ (DC1) 2013-04 ͸ͯͳਖ਼ࣾһ 2013-12 ϒοΫϚʔΫνʔϜ (ޙʹςοΫϦʔυ) ▶ ೉͍͜͠ͱ୲౰ ▶ ݕࡧٕज़, ػցֶश ▶ ຊདྷͷઐ໳͸ܕཧ࿦ ▶ Scala
  2. ͸ͯͳϒοΫϚʔΫͷྺ࢙ 2005 ೥ ϦϦʔε 2008 ೥ ίʔυϕʔεͷϦϥΠτ (DB ͸ͦͷ··) 2013

    ೥ σβΠϯͷΈϦχϡʔΞϧ 2015 ೥ ϑϧϦϥΠτϓϩδΣΫτ։࢝ 2019 ೥ ϑϧϦϥΠτ׬ྃ (DB ΋ؚΊ͢΂ͯ࡮৽)
  3. چγεςϜͰͷࠔΓͲ͜Ζ ▶ ։ൃ଎౓ͷ௿Լ ▶ ίʔυϕʔε͕ڊେ͔ͭࠞಱ .pm 400,000 ߦ / .t

    270,000 ߦ / .html 70,000 ߦ / 30+ gitmodules ▶ ϦϑΝΫλϦϯά͕௥͍͔ͭͳ͍ ▶ ύϑΥʔϚϯε্ͷ໰୊ ▶ શҬʹӨڹ͢Δ࠶ઃܭ͕ଟ਺ඞཁ ▶ αʔόίετͷ૿େ (σΟϨΫλʔ) ཷ·ͬͨύϑΥʔϚϯε issue ͥΜͿ΍Δͱ ͲΕ͘Β͍͔͔Δ? (ΤϯδχΞ) ... ͏·͍ͬͯ͘ 3 ೥ͱ͔Ͱ͔͢Ͷ
  4. ϚΠΫϩαʔϏεઓུ Ͳ͏ͳͬͨ ▶ ௨৴ํ๏ ▶ جຊతʹ HTTP Ͱ JSON Λ΍ΓͱΓ

    ▶ جຊతʹ͸ಉظత ▶ Ͳ͜Ͱ෼͚Δ͔ ▶ ڥք͚ͮΒΕͨίϯςΩετ ▶ ࠶ར༻ੑ ▶ ݴޠͷҧ͍ ▶ ϦϦʔεαΠΫϧͷҧ͍ ▶ ݴޠબ୒ Scala, Perl, Go, Python ▶ ༻్ʹ߹Θͤͯ࠷దʹબ୒ ▶ ΋ͱ΋ͱࣾ಺͸ϚϧνϦϯΨϧͳਓ͕ଟ͍
  5. ݴޠબ୒ Scala ▶ ΞϓϦέʔγϣϯͷίΞͱͳΔόοΫΤϯυ ▶ υϝΠϯϞσϧΛ͏·͘දݱ͍ͨ͠ ▶ Ϗϡʔ෦෼ΑΓ͸ߋ৽ස౓͕௿͍ Perl ▶

    BFF (Ϗϡʔ෦෼) ▶ σβΠφ΋৮ΔͷͰίϯύΠϧΛ଴ͪͨ͘ͳ͍ ▶ ଎౓༏ઌͰ׳Ε͍ͯΔ/ॻ͚Δਓ͕ଟ͍΋ͷ ▶ ߋ৽ස౓͕ߴ͍
  6. δϣϒΩϡʔ ࠔ͍ͬͯͨ ▶ TheSchwartz + WorkerManager (Perl) ▶ ॏ͍δϣϒʹϦιʔεΛ઎༗͞Ε͕ͪ ▶

    δϣϒ͕ཷ·Γ͗͢ΔͱΩϡʔ͕٧·Δ ▶ Scala Ͱ࢖͑ͳ͍ / ݴޠΛ·ͨ͛ͳ͍ ▶ ϫʔΧ؀ڥΛյͯ͠͠·͍͕ͪ ▶ ίʔυϕʔε͸ڞ௨ ▶ ؀ڥηοτΞοϓ͕·Δ͖ΓҟͳΔ ▶ ಈ࡞֬ೝ/खͰδϣϒ౤ೖ͕͍ͨ΁Μ
  7. δϣϒΩϡʔ Ͳ͏ͳͬͨ: HTTP ϕʔεͷδϣϒΩϡʔΛ৽଄ ▶ Fireworq (Go) ▶ Ωϡʔͷॲཧʹઐ೦ ▶

    ෳ਺ΩϡʔΛఆٛՄೳ (ॏ͍δϣϒΛִ཭) ▶ ಉ࣌઀ଓϫʔΧ਺ΛಈతʹઃఆՄೳ ▶ ϫʔΧ͸௨ৗͷ HTTP όοΫΤϯυ (࣮ߦ༰қ) ▶ Go ͱ MySQL Λ༻͍ͨδϣϒΩϡʔγεςϜΛ࡞Δͱ͖ʹߟ͑ͨ͜ͱ Ώ͏͏͖ϒϩά. 2014-12-04.
  8. τϥϯβΫγϣϯ ࠔ͍ͬͯͨ ▶ τϥϯβΫγϣϯॲཧΛ͍ͯ͠ͳ͔ͬͨ ▶ ࠷ॳ͸ MyISAM ͩͬͨͷͰ... ▶ ෆ੔߹͕ى͖Δ͜ͱ΋͋ͬͨ

    ▶ JSON Λڝ߹ͯ͠ॻ͖ࠐΜͰ ϑΟʔϧυ͕ফ͑Δͱ͔... sub write_key_value { # ˞໛ࣜతͳίʔυ my ($db, $obj id, $field, $value) = @ ; my $row = $db->select_row(qq{ SELECT * FROM some_table WHERE id = ? }, [ $obj id ]); my $json = $row->{json} ? decode json $row->{json} : {}; $json->{$field} = $value; # ॻ͖ࠐΉϑΟʔϧυ͸͍Ζ͍Ζ $db->query(qq{ UPDATE some_table SET json = ? WHERE id = ? }, [ encode json $json, $obj id ]); }
  9. τϥϯβΫγϣϯ Ͳ͏ͳͬͨ ▶ খ͍͞୯ҐͰ͸౰ͨΓલʹτϥϯβΫγϣϯ ▶ େ͖͍୯ҐͰ͸݁Ռ੔߹ੑΛલఏͱ͢Δ ▶ UI ͳͲ΋ͦΕલఏͰߟ͑Δ “

    ͻͱͭͷํ๏ͱͯ͠͸ɺ࣮ߦͨ͠ίϚϯυͷύϥϝʔλͱͯ͠౉ ͨ͠σʔλΛɺϢʔβʔΠϯλʔϑΣΠεʹҰ࣌తʹදࣔͤ͞Δ Α͏ͳઃܭ͕͋ΔɻଟগτϦοΩʔ͕ͩɺ࠷ऴతʹΫΤϦϞσϧ ʹ൓ө͞ΕΔͰ͋Ζ͏σʔλΛɺϢʔβʔ͕͙͢ʹݟΒΕΔΑ͏ ʹͳΔɻίϚϯυͷ࣮ߦ͕੒ޭͨ͠ͱ͖ʹɺ࣮ߦલͷݹ͍σʔλ ΛͲ͏ͯ͠΋ݟͤͨ͘ͳ͍ͷͳΒɺ͓ͦΒ͘͜Ε͕།Ұͷํ๏ͩ Ζ͏ɻ ▶ ࣮ફυϝΠϯۦಈઃܭ 4.6 ίϚϯυΫΤϦ੹຿෼཭ (CQRS) - ΫΤϦϞσϧͰͷ݁Ռ੔߹ੑͷѻ͍
  10. ɹ υϝΠϯۦಈઃܭ DDD ɹ — ϨΠϠʔ ࠔ͍ͬͯͨ ▶ ϑΝ οτϞσϧ,

    ϑΝ οτίϯτϩʔϥ ▶ ʮΞϓϦέʔγϣϯ૚ʯͷ໾ׂ͕͙ͪ͸͙ Ͳ͏ͳͬͨ (ओʹ Scala ଆ) ▶ ΫϦʔϯΞʔΩςΫνϟͳͲΛલఏʹΞϨϯδ ▶ ΞϓϦέʔγϣϯ૚ͱ͸Կ͔Λ͔ͳΓٞ࿦ ▶ ࢦ਑ΛυΩϡϝϯτԽ ▶ Perl ଆͷ෼͚ํ͸େࡶ೺
  11. ɹ υϝΠϯۦಈઃܭ DDD ɹ — ɹ υϝΠϯΦϒδΣΫτ DO ɹ ࠔ͍ͬͯͨ

    — ϑΝ οτϞσϧ ▶ 1 ͭͷΤϯςΟςΟͷΫϥε͕ 5000 ߦऑ ▶ ϝιου͕ͲΜͳ෭࡞༻Λى͔͜͢Θ͔Βͳ͍ Ͳ͏ͳͬͨ — DO ͸؆ܿʹ ▶ ݪଇͱͯ͠ෆม (ॻ͖׵͚͑ͨΕ͹ίϐʔ) ▶ (Scala) case class ▶ (Perl) Class::Accessor::Lite (::Lazy) ▶ ϑΟʔϧυͷ௥Ճ͸? ▶ (Scala) ަࠩܕͰ (ࣅඇ) ֦ுՄೳϨίʔυ ▶ (Perl) Class::Mix Ͱಈతܧঝ (Scala ͷަࠩܕͰ΍͍ͬͯΔ͜ͱͷಈత൛)
  12. ɹ υϝΠϯΦϒδΣΫτ DO ɹʹϑΟʔϧυ௥Ճ? ͲΜͳͱ͖? ▶ Կ͔ࢠཁૉΛՃ͑ͨ΋ͷʹݴٴ͍ͨ͠ͱ͖ ▶ ࢠཁૉΛՃ͑ͨͱ͖͚ͩࢀরͰ͖ͯ΄͍͠ ྫ

    my $car = Car->new(...); my $car_with_engine = $car->with_engine($engine); give_me_engine($car_with_engine->engine); my $car_with_bumper = $car->with_bumper($bumper); give_me_bumper($car_with_bumper->bumper); #give_me_engine($car_with_bumper->engine); # Τϥʔʹ͍ͨ͠ my $car_with_engine_and_bumper = $car->with_engine($engine)->with_bumper($bumper); give_me_engine($car_with_engine->engine); give_me_bumper($car_with_bumper->bumper);
  13. ɹ υϝΠϯΦϒδΣΫτ DO ɹʹϑΟʔϧυ௥Ճ? package Class::Extensible; use Class::Mix qw(mix_class); sub

    import { my $package = caller; *{"${package}::clone_with"} = sub { # Class::Mix ͰΫϥεΛ߹੒͢Δίʔυ # ׬શͳίʔυ: https://git.io/JeuHU } } package Car; use Class::Accessor::Lite (new => 1); use Class::Extensible qw(clone_with); sub with_engine { $_[0]->clone_with(’WithEngine’, engine => $_[1]); } package Car::WithEngine; use parent qw(Car); use Class::Accessor::Lite (new => 1, ro => [qw(engine)]);
  14. ɹ υϝΠϯۦಈઃܭ DDD ɹ — จԽͷܧঝ ࠔ͍ͬͯͨ id:naoya ᐌ͘ “

    υϝΠϯϩδοΫΛ App::* ʹ࣮૷͠ͳ͍͜ ͱɻ͋͘·ͰϩδοΫ͸جຊ Service::* ͔ MoCo::* ΁ ▶ Կ͕υϝΠϯϩδοΫͰԿ͕ͦ͏Ͱͳ͍͔? ▶ νʔϜͰٞ࿦Ͱ͖͍ͯͳ͔ͬͨ ▶ ΍͕ͯݴ͍఻͑ͦͷ΋ͷ͕ࣦΘΕ... ▶ Ͳ͜·Ͱ͕υϝΠϯϩδοΫ͔ᐆດͩͬͨΓ ▶ App::*͕ϏϡʔͷͨΊ͚ͩʹͳͬͯͨΓ ▶ ίϯτϩʔϥͰυϝΠϯૢ࡞͍ͯͨ͠Γ
  15. ɹ υϝΠϯۦಈઃܭ DDD ɹ — จԽͷܧঝ Ͳ͏ͳͬͨ ▶ ࣾ಺ษڧձͷ։࠵ ▶

    νϡʔτϦΞϧతͳυΩϡϝϯτΛ֦ॆ ▶ ԿΛͲ͜ʹॻ͔͘ͷࢦ਑Λఏڙ ▶ νʔϜ΁ͷಋೖࢿྉͱͯ͠ಡΉ ▶ ೔ʑυϝΠϯϞσϧ͕ద੾͔Ͳ͏͔ٞ࿦ ▶ ϢϏΩλεݴޠͱͷဃ཭ʹ͍ͭͯ΋ٞ࿦ (ຊདྷͷ DDD ͷ໨త)
  16. ް͍FW͔Βͷ୤٫ ࠔ͍ͬͯͨ — ް͍಺੡ϑϨʔϜϫʔΫ ▶ Ridge (WAF) ▶ Ruby on

    Rails ͷ ActionPack ϦεϖΫτ ▶ DBIx::MoCo (ORM) ▶ Ruby on Rails ͷ ActiveRecord ϦεϖΫτ ▶ ࣾ಺Ͱͷར༻ࣄྫ͕ͩΜͩΜݮগ ▶ ࣝऀ͕ݮͬͯ஌ݟ͕ͳ͘ͳΔ ▶ ϝϯς΋͍ͨ΁Μʹ ▶ ͩΜͩΜ࿮͔Β֎Εͨར༻͕૿Ճ “ ڍಈ͕ҙຯෆ໌ ϚδΧϧͳ͜ͱ΍Γ͕ͪ ▶ ΅͘ͷ͔Μ͕͍͖͑ͨ͞ΐ͏ͷ͏͐Ϳ͋΀Γ͚ʔ͠ΐΜ;ΕʔΉΘʔ͘ id:cho45. YAPC Asia 2011.
  17. ް͍FW͔Βͷ୤٫ ࠔ͍ͬͯͨ — WAF ▶ Ridge ▶ ҉໧ͷσΟεύονϧʔϧ (ྫ) /user/add.confirm

    → Engine::User::Add->confirm ▶ ςϯϓϨʔτ͚ͩஔ͍ͯ΋༗ޮ ▶ ࡉ͔ͳมଇϧʔϧ (.json → json ౳) ▶ ͲͷΤϯυϙΠϯτ͕༗ޮͳͷ͔೉͍͠ ▶ before filter, after filter ▶ DRY ͷͨΊͷ΂ΜΓػೳͱͯ͠ཚ༻ ▶ ύεͷॻ͖׵͑ʹ࢖͏ύλʔϯ΋... ▶ ΞΧ΢ϯτج൫ͷϞδϡʔϧ͕͜ΕΛܧঝ...
  18. ް͍FW͔Βͷ୤٫ Ͳ͏ͳͬͨ — WAF ▶ Plack + Router::Simple + ͘͝؆୯ͳ

    DSL ▶ ͢΂ͯͷϧʔςΟϯάΛ໌ࣔతʹॻ͘ GET "/{user name:$HATENA ID RE}/add" => require_login => "User" => "add"; GET "/entry/panel/" => session => "Entry::Panel" => "panel"; ▶ ύε͝ͱͷ Plack::Middleware తͳ΋ͷ ▶ ྫ => require login ະϩάΠϯ͸ 302 ▶ ίϯςΩετΦϒδΣΫτʹ Role::Tiny ▶ ྫ => session ϝιου->visitor ͕ੜ͑Δ
  19. ް͍FW͔Βͷ୤٫ ࠔ͍ͬͯͨ — ORM ▶ DBIx::MoCo ▶ มߋ͸ηογϣϯ׬ྃ࣌ʹ·ͱΊͯॻ͖ग़͠ ▶ ͕ͩଈॻ͖ग़͢->save

    ͕ݺ͹Ε͕ͪ ▶ ΠϯελϯεΩϟ ογϡͷ࢓૊Έ͕͋Δ ▶ ͕ͩΩϟ ογϡճආ൛ϝιου͕ݺ͹Ε͕ͪ ▶ τϦΨͷ࢓૊ΈͰϋϚΓ͕ͪ ▶ Ͳ͜Ͱ DB ΞΫηε͕૸Δͷ͔Θ͔Γʹ͍͘ ▶ N+1 ΫΤϦ໰୊ ▶ ͔Ώ͍ͱ͜Ζʹख͕ಧ͔ͣੜΫΤϦॻ͖͕ͪ
  20. ް͍FW͔Βͷ୤٫ Ͳ͏ͳͬͨ — ORM ͸࢖Θͳ͍ ▶ (Scala) Slick ▶ (Perl)

    DBIx::Handler + Scope::Container ▶ ΫΤϦ͸ੜͰॻ͘ ▶ N+1 ΫΤϦ໰୊ʹର͢Δ݁࿦ ▶ has-a ؔ܎Λ 1 ͚݅ͩҾ͘ϝιου͕Α͘ͳ͍ ▶ ෳ਺݅Ҿ͘ϝιου͔͠ͳ͚Ε͹΄΅ແ໰୊ ˞શମͷॻ͖ํͷελΠϧʹ΋ΑΓ·͢
  21. Perlͷόʔδϣϯ ࠔ͍ͬͯͨ ▶ 5.8 ▶ ͳ͔ͳ্͔͛ΒΕͳ͔ͬͨ ▶ ͦ΋ͦ΋ CentOS 5

    / mod perl / yum ؀ڥ ▶ Plack Խ / cpanfile Խ / Docker Խ → ࣦഊ Ͳ͏ͳͬͨ ▶ 5.2x ▶ ͢΂ً͕͍ͯͯݟ͑Δ...
  22. ͦͷଞ ▶ Ϟδϡʔϧͷಈతϩʔυͷ͍ͤͰϋϚΔ ▶ → ͳΔ΂͘΍Βͳ͍ ▶ σουίʔυ͕ଟ͔ͬͨ ▶ →

    ͋ͱͰ͘͢͝ࠔΔͷͰফ͢, ͍·͙͢! ▶ Elasticsearch ͷόʔδϣϯ্͛ΒΕͳ͍ ▶ API ͕มΘΔͱ௥ै͕͍ͨ΁Μ ▶ ݕূ͕͍ͨ͘͢͝΁Μ ▶ → Scala ΫϥΠΞϯτ͸ܕ෇͖ͳͷͰ҆৺ ▶ Twitter ౤ߘͷจࣈ਺੍ݶ ▶ Perl Ͱ࠶ݱ͢Δͷ͸ඇৗʹ೉͍͠ ▶ → Scala ͔Βެࣜ Java ύοέʔδΛར༻
  23. ɹ ֓ ೦ ࣮ ূ PoC ɹϑΣʔζ (2015ʙ) ઃܭ ▶

    DB εΩʔϚͱجຊΞʔΩςΫνϟͷૉҊ ▶ ϨϏϡʔ ▶ CTO ▶ νʔϑΤϯδχΞ ▶ Πϯϑϥ෦௕ ▶ چγεςϜࣝऀ ࣮૷ ▶ ࣺͯΔͭ΋ΓͷԾ࣮૷Λ։࢝ ▶ ྑ͍ϓϥΫςΟεΛ໛ࡧ ▶ ͜͜·ͰͰ࿩ͨ͠Α͏ͳ΍ΓํΛ΄΅֬ఆ ▶ ͏·͍ͬͨͨ͘Ί͚͖ͬΐࣺͯͣ͘ʹར༻
  24. ࣾ಺ϦϦʔε (ʙ2016) ▶ جຊػೳ͕ͻͱ௨Γಈ͘ঢ়ଶ·Ͱ࣮૷ ▶ ϒοΫϚʔΫͰ͖Δ ▶ ࣗ෼ͷϒοΫϚʔΫҰཡ͕ݟΒΕΔ ▶ ίϝϯτҰཡ͕ݟΒΕΔ

    ▶ ਓؾΤϯτϦҰཡ͕ݟΒΕΔ ▶ ࢖ͬͯΈΔ ▶ σʔλ͸ਅͬ৽ ▶ ઐ༻ϒοΫϚʔΫϨοτΛ࡞੒ ▶ ࣾ಺άϧʔϓ΢ΣΞͳͲͰར༻ͯ͠ΈΔ ▶ ։ൃํࣜ: ී௨ͷ৽ن։ൃͷΞδϟΠϧͱಉ͡
  25. ϓϩδΣΫτͷऩଋ (ʙ2019) ࢒Γͷ੾Γସ͑ ▶ API ͷΈͷػೳ ▶ ඇಉظॲཧͷΈͰ࢖ΘΕΔॲཧ ▶ ߋ৽ܥ

    ׬શ੾Γସ͑ ▶ چϦιʔε͝ͱʹશґଘؔ܎Λચ͍ग़͠ ▶ ΤϯυϙΠϯτ౳ ˠ ΤϯςΟςΟ/Ϧιʔε ▶ ґଘؔ܎Λసஔ ▶ ֤Ϧιʔε issue ʹ࣮૷ issue Λྻڍ ▶ ґଘ͕ͳ͘ͳͬͨچϦιʔε͔Βॱ࣍ఫୀ