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

Perlに比べてPHPが不便(主観です) ああ…だから僕は…

uzulla
May 21, 2016

Perlに比べてPHPが不便(主観です) ああ…だから僕は…

LT at PHP Conference Fukuoka 2016

uzulla

May 21, 2016
Tweet

More Decks by uzulla

Other Decks in Programming

Transcript

  1. Perlʹൺ΂ͯPHP͕ෆศ
    ʢओ؍Ͱ͢ʣ
    ͋͋…͔ͩΒ๻͸…
    • date: 20160521
    • at: PHPΧϯϑΝϨϯε෱Ԭ 2016
    • speaker: uzulla

    View full-size slide

  2. ࣗݾ঺հ
    • ౦ͷํͷ͏ͣΒ(uzulla)Ͱ͢
    • ମܕతʹ΋ʮLʢΤϧʣʯͳํ
    Ͱ͢
    • ʢ෱Ԭͷudzura͞Μ͸ମܕ͸
    ʮRʢϨΪϡϥʔʣʯͰ͢
    Ͷʣ
    • Perlք۾Ͱ͸PHPͷਓͱ͍Θ
    Ε·͕͢ɺPHPք۾Ͱ͸Perl
    ͷਓͱ͍ΘΕ͍ͯΔؾ͕͠·
    ͢

    View full-size slide

  3. Perlʹൺ΂ͯ
    PHP͕ෆศ
    ʢओ؍Ͱ͢ʣ

    View full-size slide

  4. ʮPerlͷΧοίΠΠϠπ
    ʢओ؍ʣ
    ΛPHPͰ΋͔͍͍ͭͨ
    ͧʂʂʯ

    View full-size slide

  5. ͋͋…͔ͩΒ๻͸…

    View full-size slide

  6. yay
    • h#ps:/
    /github.com/marcioAlmada/yay
    • Yay is a high level PHP preprocessor
    • Not ready for real world usage yet !

    View full-size slide

  7. ϓϦϓϩηοαͱ͸ʁ
    • Cͱ͔Ͱ͓ೃછΈ
    • ίϯύΠϧ࣌ʹίʔυΛಈతʹม׵
    • ఆ਺΍ɺϚΫϩஔ׵
    • yay͸PHPίʔυΛม׵͠ɺPHPίʔυͱͯ͠ग़ྗ
    ͢ΔτϥϯεύΠϥΈ͍ͨͳͷ
    • ࠓճ͸PHPͷߏจΛվ଄͢Δͷʹ͔͍ͭ·͢

    View full-size slide

  8. ͱΓ͋͑ͣࢼ͢πʔϧ
    • github.com/uzulla/yay-tester.php
    • evalͯ͠ΔͷͰةݥͰ͢!खݩͰ͔͍ͭ·͠ΐ͏
    • ʮ҆શͳϨϯαόͳΒ͏͔ͯ͝͠΋͍͍…ʁʯ
    ʢԥΒΕͦ͏ͳͷͰࣗॏ͠·ͨ͠ʣ
    • PHP>=7
    ʢevalΛtryʙcatch (\Throwable $e) {}Ͱ
    ଈࢮճආʣ

    View full-size slide

  9. say
    • say "hogehoge";
    • say͸echoΑΓҰจࣈগͳ͍ʂ
    • վߦ͕෇͘ͷ͕࠷ߴʹศརʂ
    • ʮPerl6͡ΌΜʯ
    ʮp5Ͱ΋use feature 'say'͢Ε͹…ʯ

    View full-size slide

  10. # ͜ͷʮmacroʯͱ͍͏ॴΛyay͕ࢀর͢Δ
    macro { say ·string()·message } >> {
    echo ·message;
    echo PHP_EOL;
    }
    # ͜͜·Ͱmacro
    say "say!";
    say "yes!";

    View full-size slide

  11. say "say!";
    say "yes!";
    // ↓
    echo "say!";
    echo PHP_EOL;
    echo "yes!";
    echo PHP_EOL;

    View full-size slide

  12. unless
    • unless($flag){}
    • if(!$flag){}ͱಉ͡
    • ʮ!Λॻ͚͹͍͍͡Όͳ͍ʯ
    ʮif( ! isKakin())Έ͍ͨͳͷ୔ࢁଓ͘ͱͭΒ͍…ʯ
    ʮisHikakin()Λͭ͘Ε͹͑͑΍Μʯ
    ʮͳΔ΄Ͳʁʯ

    View full-size slide

  13. macro {
    unless (···expression) { ···body }
    } >> {
    if (! (···expression)) { ···body }
    }
    $isSuccess = true;
    unless($isSuccess){
    echo('failed');
    }

    View full-size slide

  14. $isSuccess = true;
    unless($isSuccess){
    echo('failed');
    }
    // ↓
    $isSuccess = false;
    if (! ($isSuccess)) {
    echo('failed');
    }

    View full-size slide

  15. range ԋࢉࢠ
    • for(1 .. 10){ print $_; }
    • ਖ਼௚͔ͳΓཉ͍͠

    View full-size slide

  16. macro {
    foreach ( T_LNUMBER·S .. T_LNUMBER·E
    as T_VARIABLE·INDEX )
    { ···body }
    } >> {
    foreach ( range(T_LNUMBER·S , T_LNUMBER·E)
    as T_VARIABLE·INDEX )
    { ···body }
    }
    foreach( 1 .. 10 as $_ ){ echo $_; }

    View full-size slide

  17. foreach( 1 .. 10 as $_ ){
    echo $_;
    }
    // ↓
    foreach ( range(1 , 10) as $_ ){
    echo $_;
    }

    View full-size slide

  18. range ԋࢉࢠ ͦͷ̎
    • ʮrange()Ͱforeachͱ͔μϝͰ͠ΐʯ
    ʮ͸͍ʯ
    • ʢੲͷPerl͸PHPಉ༷ʹڊେ഑ྻ͕Ͱ͖͍ͯͨ
    ʢΒ͍͠ʣʣ
    • ʢࠓճ͸࣮૷͠ͳ͍͚Ͳ('a' .. 'z')ͳͲ΋

    View full-size slide

  19. macro {
    foreach ( T_LNUMBER·S .. T_LNUMBER·E
    as T_VARIABLE·INDEX )
    { ···body }
    } >> {
    $__itelatorGenerator =
    itelatorGenerator(T_LNUMBER·S, T_LNUMBER·E);
    foreach ( $__itelatorGenerator as T_VARIABLE·INDEX )
    { ···body }
    }
    function itelatorGenerator($init, $fin){
    $num = $init;
    while(1){
    if( $fin < $num ) { return $num++; }
    yield $num++;
    }
    }
    foreach( 1 .. 10 as $_ ){ echo $_; }

    View full-size slide

  20. function itelatorGenerator($init, $fin){
    $num = $init;
    while(1){
    if( $fin < $num ) { return $num++; }
    yield $num++;
    }
    }
    // ͜͜·Ͱڞ௨
    foreach( 1 .. 10 as $_ ){ echo $_; }
    // ↓
    $__itelatorGenerator·cfcd208495d565ef66e7dff9f98764da
    = itelatorGenerator(1, 10);
    foreach ( $__itelatorGenerator·cfcd208495d565ef66e7dff9f98764da as $_ )
    { echo $_; }

    View full-size slide

  21. ਖ਼نදݱϚονͱஔ׵
    • Ϛον
    • if( "123" =~ /2/ ){ }
    • ஔ׵
    • $abc =~ s/a/A/;
    • ݸਓతʹ͸݁ߏ޷͖
    • ʮPerlه߸ଟਿʯ
    ʮperlopͰάάΕʯ

    View full-size slide

  22. macro {
    T_VARIABLE·A =~ /T_STRING·B/
    } >> {
    preg_match(
    '/'. ··stringify(T_STRING·B) .'/u',
    T_VARIABLE·A
    )
    }
    if($abc =~ /a/){ echo 1; }

    View full-size slide

  23. if($abc =~ /a/){
    echo 1;
    }
    // ↓
    if(preg_match( '/'. 'a' .'/u' ,$abc )){
    echo 1;
    }
    # օ͞Μ͕͍͍͍ͨ͜ͱ͸ղΔ

    View full-size slide

  24. macro {
    T_VARIABLE·A =~ s/T_STRING·B/T_STRING·C/
    } >> {
    T_VARIABLE·A =
    preg_replace(
    '/'. ··stringify(T_STRING·B) .'/u',
    ··stringify(T_STRING·C) ,
    T_VARIABLE·A
    )
    }
    $abc = 'abc';
    $abc =~ s/a/v/;
    echo $abc;

    View full-size slide

  25. $abc =~ s/a/v/;
    // ↓
    $abc = preg_replace(
    '/' . 'a' . '/u',
    'v' ,
    $abc
    );

    View full-size slide

  26. ༨ஊ:JS෩ਖ਼نදݱϚον
    • if($abc./a/){ ... }
    • ʮOOPͬΆ͍ʂʯ
    ʮݩʑΦϒδΣΫτࢦ޲ݴޠ͔ͩͧͬ͠Γ͠Ζʯ
    • ʮPHPͳΒ −>Ͱ͸ʁʯ
    ʮͤ΍ͳʯ

    View full-size slide

  27. macro {
    if( T_VARIABLE·A./T_STRING·B/ ){ ···body }
    } >> {
    if( preg_match(
    '/'. ··stringify(T_STRING·B) .'/u' ,
    T_VARIABLE·A ) )
    { ···body }
    }
    $abc = 'abc';
    if($abc./a/){
    echo 1;
    }

    View full-size slide

  28. if($abc./a/){ echo 1; }
    // ↓
    if( preg_match(
    '/'. 'a' .'/u' ,
    $abc
    )
    ){ echo 1; }

    View full-size slide

  29. yadayada
    • ...
    • ʮޙͰ࣮૷͢Δ͔Β...ʯͱ͍͏࣌ͷʮ...ʯ
    • ౸ୡ͢Δͱɺྫ֎্͕͕Δ
    • //TODOΑΓ΋Θ͔Γ΍͍͢…͔΋…͠Εͳ͍

    View full-size slide

  30. macro { ... } >> {
    throw new \Exception ('Unimplemented');
    }
    if(1){
    ...
    }

    View full-size slide

  31. if(1){
    ...
    }
    // ↓
    if(1){
    throw new \Exception ('Unimplemented');
    }

    View full-size slide

  32. block scope
    • {ʙ}
    • ϒϩοΫͷதͰείʔϓ͕ग़དྷΔ
    • ͋ΔҙຯҰ൪ϚΫϩͬΆ͍
    • ΊͬͪΌ΄͍͠ʂʂʂ

    View full-size slide

  33. macro { { ···body } } >> {
    ( function( $arg ) {
    extract( $arg );
    ···body
    } ) ( get_defined_vars() ) ;
    }
    $abc = 'abc';
    {
    $abc = 'def';
    echo $abc, PHP_EOL;
    }
    echo $abc, PHP_EOL;

    View full-size slide

  34. {
    $abc = 'def';
    }
    // ↓
    ( function( $arg·cfSNIPda ) {
    extract( $arg·cfSNIPda );
    $abc = 'def';
    } ) ( get_defined_vars() ) ;

    View full-size slide

  35. use
    • ʮPHPͷuseͬͯͳΜͳͷɺಡΈࠐΜͰ͘Εͳ͍ͷ
    Α͘Θ͔Βͳ͍Μ͚ͩͲ…ʯʢ༑ਓͷJVMܥϓϩ
    άϥϚஊʣ
    ʮͨɺ͔ͨ͠ʹ…ʯ
    • useͰຊ౰ʹrequire_once͢Ε͹ղܾ

    View full-size slide

  36. macro {
    use ·ns()·type ;
    } >> {
    use ·type ;
    __require( ··stringify(·type) ) ;
    }
    function __require($class){
    $array = explode('\\', ltrim($class, '\\'));
    $path = implode('/', $array);
    $filename = $path.'.php';
    require_once($filename);
    }
    use \This\Is\Test;

    View full-size slide

  37. use \This\Is\Test;
    // ↓
    use \This\Is\Test ;
    __require( '\This\Is\Test' ) ;

    View full-size slide

  38. use strict;
    use warnings;
    • ͍ܰΤϥʔͰ΋ऴྃ͢Δ
    • ͋΍͍͠ॴͰܯࠂ͢Δ
    • ʢຊ౰͸΋͏ͪΐͬͱҙຯ͕͋Δʣ
    • ʢηοτ͍ͯ͠ΔΤϥʔϋϯυϥ࡞๏͸ݸਓతझ
    ຯͰ͢ʣ

    View full-size slide

  39. macro { use strict; } >> {
    set_error_handler(
    function($errno, $errstr, $errfile, $errline){
    throw new \Error($errstr);
    }
    );
    }
    macro { use warnings; } >> { error_reporting(-1); }
    use strict;
    use warnings;
    echo $a;

    View full-size slide

  40. use strict;
    use warnings;
    // ↓
    set_error_handler(
    function(
    $errno·cfSNIPda,
    $errstr·cfSNIPda,
    $errfile·cfSNIPda,
    $errline·cfSNIPda
    ){
    throw new \Error($errstr·cfSNIPda);
    }
    );
    error_reporting(-1);

    View full-size slide

  41. ·ͱΊ
    • yayͬͯ݁ߏศརͰ͸ʂʢʁʣ
    • ʮҰਓϓϩδΣΫτ΍झຯͳΒͳʂʯ
    • ஔ׵ͱ͔Ͱ͸ͳ͍ͷͰɺ
    ʢͪΌΜͱॻ͚͹ʣ͔ͳΓյΕͮΒ͍
    • ग़ྗ͞ΕΔͷ͸ɺຊ౰ͷPHPͳͷͰ҆৺ʢʁʣ
    • ୯७ͳϧʔλʔఆٛͷDSLͳΒͭ͘Ε·ͨ͠

    View full-size slide

  42. ຊ౰ʹ΍Δਓ΁ͷίϝϯτ
    • yayɺυΩϡϝϯτ͕ςετίʔυ͔͠ͳ͍ͷͰௐ
    ΂Δͷ͕େม
    • τʔΫϯछͷT_VARIABLE౳͸
    github/nikic/PHP-Parser
    • ύʔαʔͷ·ls౳͸
    github/marcioAlmada/yay/src/
    parsers.php
    • ʮͱʹ͔࣮͘૷ͱςετίʔυΛݟΔΜͩʯ

    View full-size slide

  43. • ·ͱ.ͱɾΛؒҧ͑ͯେม
    • middle dot
    • ʮ·(00B7)ͬͯɺීஈͲ͏΍ͬͯೖྗ͢ΔΜ΍…ʯ
    • ʮதࠇΛ·(00B7)ʹม׵͢Δpreprocessor͕ඞཁͰ
    ͸ʯ

    View full-size slide

  44. __halt_compiler();

    View full-size slide

  45. ʮyapc8oji Ͱάάͬͯ͘ΕཔΉʯ
    τʔΫԠืͯ͘͠Εʂʂ̍

    View full-size slide

  46. ͓·͚ɿshort closure
    • ( )->{ }

    View full-size slide

  47. macro {
    (···condition) -> { ···body }
    } >> {
    function ( ···condition ) { ···body }
    }
    $a = ($v)->{ echo $v; };
    $a('abc');

    View full-size slide

  48. $a = ($v)->{ echo $v; };
    // ↓
    $a = function ( $v ) { echo $v; };

    View full-size slide

  49. Defined-Or, //= ԋࢉࢠ
    • $a //= 'default';
    • ʢ//͸??ͱಉ͡ʣ
    • ຊؾͰཉ͍͠
    • 7.xͰདྷΔʢ͚ͲઌऔΓͱ͍͏͜ͱͰʣ
    => https://wiki.php.net/rfc/
    null_coalesce_equal_operator

    View full-size slide

  50. macro { T_VARIABLE·A ??= } >> {
    T_VARIABLE·A = T_VARIABLE·A ??
    }
    $a ??= 123;
    echo $a;

    View full-size slide

  51. $a ??= 123;
    echo $a;
    // ↓
    $a = $a ?? 123;
    echo $a;

    View full-size slide

  52. splitͱjoin
    • ʮͲ͏ͯ͠΋Explode/Implode͕׳Εͳ͍ʯ
    ʮ׳ΕΖʯ
    ʮͳͥจࣈ਺Λ૿΍͢ํ޲ʹߦͬͨͷ͔ʯ
    ʮఘΊΖʯ
    • PHP7Ͱ͍ͭʹফ໓͠·ͨ͠Ͷ

    View full-size slide

  53. macro { split } >> { mb_split }
    macro { join } >> { implode }
    print_r( split(",", "a,b,c") );
    print_r( join(",", ["a","b","c"]) );
    # PHP7Ͱsplit()͕ͳ͘ͳͬͯ΋
    # mb_split͸ͷ͍ͬͯ͜ΔΜͩΑͳ͋…

    View full-size slide

  54. split(",", "a,b,c");
    join(",", ["a","b","c"]);
    // ↓
    mb_split(",", "a,b,c");
    implode(",", ["a","b","c"]);

    View full-size slide