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

モダンPerlリファクタリング #yapcasia

Naoya Ito
September 20, 2013

モダンPerlリファクタリング #yapcasia

YAPC Asia 2013

Naoya Ito

September 20, 2013
Tweet

More Decks by Naoya Ito

Other Decks in Technology

Transcript

  1. Ϟμϯ1FSMϦϑΝΫλϦϯά
    [email protected]

    View Slide

  2. View Slide

  3. .BSLEPXO5P*OBP
    NEJOBP

    View Slide

  4. #  Hello,  World  
     
    *  list  1  
    *  list  2
    ■Hello,  World  
    ・list  1  
    ・list  2

    View Slide

  5. View Slide

  6. ߏ଄తʹػೳΛ͚ͭՃ͑ʹ͍͘ϓϩ
    άϥϜʹ৽نػೳΛ௥Ճ͠ͳ͚Ε͹ͳ
    Βͳ͍৔߹ʹ͸ɺ·ͣػೳ௥Ճ͕؆୯
    ʹͳΔΑ͏ʹϦϑΝΫλϦϯάΛͯ͠
    ͔Β௥ՃΛߦ͏͜ͱɻ 1

    ʰϦϑΝΫλϦϯάϓϩάϥϛϯάͷମ࣭վળςΫχοΫʱ
    ϚʔνϯɾϑΝ΢ϥʔ

    View Slide

  7. "'5&3
    package  Text::Md2Inao::Builder::Inao;  
    use  parent  qw/Text::Md2Inao::Builder/;  
    use  Text::Md2Inao::Builder::DSL;  
     
    case  default  =>  sub  {  
           my  ($c,  $h)  =  @_;  
           fallback_to_html($h);  
    };  
     
    case  a  =>  sub  {  
           my  ($c,  $h)  =  @_;  
           my  $url      =  $h-­‐>attr('href');  
           my  $title  =  $h-­‐>as_trimmed_text;  
           if  ($url  and  $title)  {  
                   return  sprintf  "%s◆注/◆%s◆/注◆",  $title,  $url;  
           }  else  {  
                   return  fallback_to_html($h);  
           }  
    };  
     
    ...  

    View Slide

  8. લఏ

    View Slide

  9. ಓ۩
    •  $BSUPODQBOpMF
    •  (JUIVC
    •  ςετ
    •  $*ɺ(VBSE

    View Slide

  10. ϦϑΝΫλϦϯάͷྲྀΕ
    •  Լ४උ
    –  σΟϨΫτϦΛ੔͑ͯ(JUIVCʹ
    –  $1"/Ϟδϡʔϧચ͍ग़͠
    •  શମΛϞδϡʔϧԽͯ͠"1*ఆٛ
    •  &OEUP&OEͷςετ
    •  ҎԼ܁Γฦ͠
    –  ࡉ͔͍ςετ
    –  ϦϑΝΫλϦϯά
    •  ճؼςετΛཷΊΔ

    View Slide

  11. Լ४උ

    View Slide

  12. σΟϨΫτϦΛ੔͑ͯ(JUIVC΁
    •  $1"/Ϟδϡʔϧͱಉ͡σΟϨΫτϦϨΠ
    Ξ΢τʹ͢Δ
    – ֤छπʔϧͷԸܙʹ༩Δ
    •  QSPWFɺ$BSUPOɺ(VBSEɺ5SBWJT$*

    View Slide

  13. View Slide

  14. $1"/Ϟδϡʔϧચ͍ग़͠
    •  $BSUPODQBOpMF
    •  ΑΓϙʔλϒϧʹ
    #  cpanfile  
    requires  'Text::Markdown';  
    requires  'HTML::TreeBuilder';  
    requires  'Unicode::EastAsianWidth';  
    requires  'Pod::Usage';  
    ...  

    View Slide

  15. DBSUPOFYFD
    %  carton  install  
    %  carton  exec  perl  bin/md2inao.pl  
    •  ϥΠϒϥϦΛϩʔΧϧύεલఏʹ ີ෧ػೳ

    –  ʮଞͰೖΕͨϞδϡʔϧͰಈ͍ͯͨʯΛճආ
    •  ґଘϞδϡʔϧͷόʔδϣϯΛݫີʹݻఆ
    DBSUPOFYFD͠ͳ͕Β଍Γͳ͍ϞδϡʔϧΛ
    DQBOpMFʹ௥ه˰͋ΒෆࢥٞɺϞδϡʔϧҰཡ
    ͷͰ͖͕͋Γ

    View Slide

  16. ͍͟ϦϑΝΫλϦϯά

    View Slide

  17. શମΛͻͱͭͷϞδϡʔϧʹ
    my  $inao  =  Text::Md2Inao-­‐>new({  
       default_list                      =>  'disc',  
       max_list_length                =>  63,  
       max_inline_list_length  =>  55,  
    });  
     
    print  $inao-­‐>parse($markdown)  

    View Slide

  18. package  Text::Md2Inao;  
     
    sub  parse  {  
       my  $markdown  =  shift;  
       ...  
       return  $inao;  
    }  
    ·ͣ͸ͬ͘͟Γ෴͏

    View Slide

  19. ςετ͕ॻ͚Δ
    use  Test::More;  
     
    my  $inao  =  Text::Md2Inao-­‐>new  
    my  $out  =  $inao-­‐>parse("#  Hello,  World");  
    is  $out,  "■Hello,  World";  
     
    done_testing;  

    View Slide

  20. %  carton  exec  -­‐Ilib  -­‐-­‐  prove  t/01_api.t  
    t/01_api.t  ..  ok  
    All  tests  successful.  
    Files=1,  Tests=1,    0  wallclock  secs  (  0.02  usr    
    0.00  sys  +    0.09  cusr    0.00  csys  =    0.11  CPU)  
    Result:  PASS  

    View Slide

  21. ϦϑΝΫλϦϯάΛ։࢝͢Δͱ͖ɺ
    ࠷ॳʹ͢Δ͜ͱ͸ৗʹಉ͡Ͱ͢ɻର৅
    ͱͳΔίʔυʹ͍͖ͭͯͪΜͱͨ͠ς
    ετ܈Λ࡞Γ্͛Δ͜ͱͰ͢ 1

    ʰϦϑΝΫλϦϯάϓϩάϥϛϯάͷମ࣭վળςΫχοΫʱ
    ϚʔνϯɾϑΝ΢ϥʔ

    View Slide

  22. جຊઓུ
    •  ࣮ߦ؀ڥͱΞϓϦέʔγϣϯΛ෼཭͢Δ
    – $6*ͳΒ45%*/45%065ͷ*0
    – 8FCΞϓϦͳΒ)551αʔόʔ

    •  ෼཭ͨ͠ΞϓϦέʔγϣϯଆͷҰ൪େ͖
    ͳ"1*ͷςετΛॻ͘
    – ͜Ε͕&OEUP&OEͷςετ

    View Slide

  23. &OEUP&OEͷςετ͔Β࢝ΊΔ
    •  ·ͣ͸֎ଆͷʮৼΔ෣͍ʯΛอূ
    – ͦͷͨΊͷ֎෦"1*ͬ͘͟ΓϞδϡʔϧԽ

    View Slide

  24. ϦϑΝΫλϦϯά ໊ࢺ
    ֎෦͔Β
    ݟͨͱ͖ͷৼΔ෣͍Λอͪͭͭɺཧղ
    ΍मਖ਼͕؆୯ʹͳΔΑ͏ʹɺιϑτ
    ΢ΣΞͷ಺෦ߏ଄ΛมԽͤ͞Δ͜
    ͱɻ 1

    ʰϦϑΝΫλϦϯάϓϩάϥϛϯάͷମ࣭վળςΫχοΫʱ
    ϚʔνϯɾϑΝ΢ϥʔ

    View Slide

  25. NEJOBPͰ͸5FTU#BTF
    use  Test::Base;    
    use  Text::Md2Inao;  
     
    plan  tests  =>  1  *  blocks;    
    run_is  in  =>  'expected';  
     
    sub  md2inao  {  Text::Md2Inao-­‐>new-­‐>parse($_)  }  
     
    __END__  
    ===  
    -­‐-­‐-­‐  in  md2inao  
    #  見出し1(大見出し、節)    
    -­‐-­‐-­‐  expected  
    ■見出し1(大見出し、節)  
     
    ===  
    -­‐-­‐-­‐  in  md2inao  
    ##  見出し2(中見出し、項)    
    -­‐-­‐-­‐  expected  
    ■■見出し2(中見出し、項)  

    View Slide

  26. 8FCΞϓϦέʔγϣϯͷ৔߹
    •  1MBDLԽͯ͠1MBDL5FTUͳͲ
    use  Test::More;  
    use  Plack::Test;  
     
    ...  
     
    #  $app  :  PSGI  application  
    test_psgi  $app,  sub  {    
       like  shift-­‐>(GET  "/amazlet/")-­‐>content,  qr//    
    };  

    View Slide

  27. $(*ͳΜͰ͚͢Ͳŋŋŋ
    •  1MBDL"QQ8SBQ$(*Ͱ1MBDLԽ͢Δ
    use  Plack::Builder;  
    use  Plack::App::WrapCGI;  
     
    builder  {  
       mount  "/cgi-­‐bin/amazlet.cgi"  =>  Plack::App::WrapCGI-­‐>new(  
           script  =>  './htdocs/amazlet.cgi',  execute  =>  1  
       )-­‐>to_app;  
    };  

    View Slide

  28. ࣮ߦ؀ڥ͕ີ݁߹ͨ͠
    ಠࣗ'8ͳΜͰ͚͢Ͳŋŋŋ
    •  IFBEMFTTϒϥ΢βͰ&&ςετ͢Δ
    – DBQZCBSBXFCLJUIFBEMFTTͱ͔
    – ͦͷޙɺ1MBDLԽͯ͠'8Λ෼཭
    3VCZ͚ͩͲͳ

    View Slide

  29. ͋ͱ͸ɺҎԼ܁Γฦ͠
    •  ΑΓཻ౓ͷࡉ͔͍ςετΛ௥Ճ
    – ࡉ͔͍σʔλͰͷ&OEUP&OE
    – ಺෦ϞδϡʔϧͷϢχοτςετ
    •  ϦϑΝΫλϦϯάΛਐΊΔ
    ςετ͑͋͞Ε͹ɺͲΜͳʹϨΨ
    γʔͰ΋ϦϑΝΫλϦϯά͸೉͘͠
    ͳ͍ɻ

    View Slide

  30. όάϨϙʔτΛड͚औͬͨΒɺ·ͣ
    ͦͷόάΛ໌Β͔ʹ͢ΔͨΊͷ୯ମς
    ετΛॻ͚ɻ 1

    ʰϦϑΝΫλϦϯάϓϩάϥϛϯάͷମ࣭վળςΫχοΫʱ
    ϚʔνϯɾϑΝ΢ϥʔ

    View Slide

  31. ճؼςετΛཷΊࠐΉ
    %  ls  t/99_rt_*  |  cat  
    t/99_rt_blockquote_id.t  
    t/99_rt_bold.t  
    t/99_rt_indent.t  
    t/99_rt_list.t  
    t/99_rt_list_id.t  
    t/99_rt_list_in_column.t  
    t/99_rt_nested_parentheses.t  
    t/99_rt_paragraph.t  
    t/99_rt_quotes.t  
    t/99_rt_ruby_in_footnote.t  
    t/99_rt_table_indent.t  
    ...  
    •  όάൃݟˠճؼςετॻ͘ˠςετ௨͢

    View Slide

  32. ίπ

    View Slide

  33. ςετ͸͜·Ίʹճͦ͏

    View Slide

  34. ςετΛසൟʹͤΑɻίϯύΠϧ࣌
    ʹ͸ςετΛہॴԽͯ͠ɺ೔ʹ࠷௿
    ౓͸͢΂ͯͷςετΛ࣮ߦͤ
    Αɻ 1

    ʰϦϑΝΫλϦϯάϓϩάϥϛϯάͷମ࣭վળςΫχοΫʱ
    ϚʔνϯɾϑΝ΢ϥʔ

    View Slide

  35. ܧଓతΠϯςάϨʔγϣϯ
    5SBWJT$*

    View Slide

  36. (VBSEHVBSEUBQ
    h"p://hitode909.hatenablog.com/entry/2013/05/11/190623

    View Slide

  37. ςετ͸ແཧͤͣ
    ʮ΄Ͳ΄Ͳʯఔ౓ʹ

    View Slide

  38. ෆ׬શͳςετͰ΋ɺॻ͍࣮ͯߦ͢
    Δํ͕ɺ࣮ߦͰ͖ͳ͍׬શͳςετ
    ΑΓ΋·ͩ͠ɻ 1

    ʰϦϑΝΫλϦϯάϓϩάϥϛϯάͷମ࣭վળςΫχοΫʱ
    ϚʔνϯɾϑΝ΢ϥʔ

    View Slide

  39. %))΋͜͏ݴ͍ͬͯΔ
    •  ʮΧόϨοδ͸Λ໨ࢦ͞ͳ͍ʯ
    •  ʮ࡞ۀͷ൒෼Ҏ্͕ςετɺ͸͓͔͍͠ʯ
    •  ʮςετϑΝʔετʹͩ͜ΘΒͳ͍ʯ
    – ͕ςετϑΝʔετͰ͕ςετΞ
    ϑλʔ
    h"p://37signals.com/svn/posts/3159-­‐[email protected]­‐like-­‐the-­‐tsa

    View Slide

  40. ςετ͸ɺ͍͍ͩͨͰɻ
    Ͱ΋සൟʹ࣮ߦ
    •  ·ͣ͸ϦϑΝΫλϦϯά͕ා͘ͳ͍ఔ౓ʹς
    ετ͕͋Ε͹͍͍
    –  ϦϑΝΫλϦϯά͕ਐΉͱςετ͕ॻ͖΍͘͢
    –  ࣗવͱΧόϨοδ͸্͕Δ
    •  ϦϑΝΫλϦϯάதʹݟ͚ͭͨόάͷճؼς
    ετΛཷΊΑ͏
    –  ࣗવͱݎ࿚ʹͳ͍ͬͯ͘
    •  ࡞ͬͨςετ͸ͪΐͬͱߋ৽ͷ౓ɺසൟʹ࣮
    ߦ͠Α͏

    View Slide

  41. (PPE+PC
    package  Text::Md2Inao::Builder::Inao;  
    use  parent  qw/Text::Md2Inao::Builder/;  
    use  Text::Md2Inao::Builder::DSL;  
     
    case  default  =>  sub  {  
           my  ($c,  $h)  =  @_;  
           fallback_to_html($h);  
    };  
     
    case  a  =>  sub  {  
           my  ($c,  $h)  =  @_;  
           my  $url      =  $h-­‐>attr('href');  
           my  $title  =  $h-­‐>as_trimmed_text;  
           if  ($url  and  $title)  {  
                   return  sprintf  "%s◆注/◆%s◆/注◆",  $title,  $url;  
           }  else  {  
                   return  fallback_to_html($h);  
           }  
    };  
     
    ...  

    View Slide