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

271fad8d53cd1f12f2b4b6d38e3d7bd3?s=47 uzulla
May 21, 2016

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

LT at PHP Conference Fukuoka 2016

271fad8d53cd1f12f2b4b6d38e3d7bd3?s=128

uzulla

May 21, 2016
Tweet

Transcript

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

    • speaker: uzulla
  2. ࣗݾ঺հ • ౦ͷํͷ͏ͣΒ(uzulla)Ͱ͢ • ମܕతʹ΋ʮLʢΤϧʣʯͳํ Ͱ͢ • ʢ෱Ԭͷudzura͞Μ͸ମܕ͸ ʮRʢϨΪϡϥʔʣʯͰ͢ Ͷʣ

    • Perlք۾Ͱ͸PHPͷਓͱ͍Θ Ε·͕͢ɺPHPք۾Ͱ͸Perl ͷਓͱ͍ΘΕ͍ͯΔؾ͕͠· ͢
  3. Perlʹൺ΂ͯ PHP͕ෆศ ʢओ؍Ͱ͢ʣ

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

  5. ͋͋…͔ͩΒ๻͸…

  6. ΠΤʔΠʂ

  7. yay • h#ps:/ /github.com/marcioAlmada/yay • Yay is a high level

    PHP preprocessor • Not ready for real world usage yet !
  8. ϓϦϓϩηοαͱ͸ʁ • Cͱ͔Ͱ͓ೃછΈ • ίϯύΠϧ࣌ʹίʔυΛಈతʹม׵ • ఆ਺΍ɺϚΫϩஔ׵ • yay͸PHPίʔυΛม׵͠ɺPHPίʔυͱͯ͠ग़ྗ ͢ΔτϥϯεύΠϥΈ͍ͨͳͷ

    • ࠓճ͸PHPͷߏจΛվ଄͢Δͷʹ͔͍ͭ·͢
  9. ͱΓ͋͑ͣࢼ͢πʔϧ • github.com/uzulla/yay-tester.php • evalͯ͠ΔͷͰةݥͰ͢!खݩͰ͔͍ͭ·͠ΐ͏ • ʮ҆શͳϨϯαόͳΒ͏͔ͯ͝͠΋͍͍…ʁʯ ʢԥΒΕͦ͏ͳͷͰࣗॏ͠·ͨ͠ʣ • PHP>=7

    ʢevalΛtryʙcatch (\Throwable $e) {}Ͱ ଈࢮճආʣ
  10. say • say "hogehoge"; • say͸echoΑΓҰจࣈগͳ͍ʂ • վߦ͕෇͘ͷ͕࠷ߴʹศརʂ • ʮPerl6͡ΌΜʯ

    ʮp5Ͱ΋use feature 'say'͢Ε͹…ʯ
  11. <?php # ͜ͷʮmacroʯͱ͍͏ॴΛyay͕ࢀর͢Δ macro { say ·string()·message } >> {

    echo ·message; echo PHP_EOL; } # ͜͜·Ͱmacro say "say!"; say "yes!";
  12. say "say!"; say "yes!"; // ↓ echo "say!"; echo PHP_EOL;

    echo "yes!"; echo PHP_EOL;
  13. say! yes!

  14. unless • unless($flag){} • if(!$flag){}ͱಉ͡ • ʮ!Λॻ͚͹͍͍͡Όͳ͍ʯ ʮif( ! isKakin())Έ͍ͨͳͷ୔ࢁଓ͘ͱͭΒ͍…ʯ

    ʮisHikakin()Λͭ͘Ε͹͑͑΍Μʯ ʮͳΔ΄Ͳʁʯ
  15. <?php macro { unless (···expression) { ···body } } >>

    { if (! (···expression)) { ···body } } $isSuccess = true; unless($isSuccess){ echo('failed'); }
  16. $isSuccess = true; unless($isSuccess){ echo('failed'); } // ↓ $isSuccess =

    false; if (! ($isSuccess)) { echo('failed'); }
  17. failed

  18. range ԋࢉࢠ • for(1 .. 10){ print $_; } •

    ਖ਼௚͔ͳΓཉ͍͠
  19. <?php 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 $_; }
  20. foreach( 1 .. 10 as $_ ){ echo $_; }

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

  22. range ԋࢉࢠ ͦͷ̎ • ʮrange()Ͱforeachͱ͔μϝͰ͠ΐʯ ʮ͸͍ʯ • ʢੲͷPerl͸PHPಉ༷ʹڊେ഑ྻ͕Ͱ͖͍ͯͨ ʢΒ͍͠ʣʣ •

    ʢࠓճ͸࣮૷͠ͳ͍͚Ͳ('a' .. 'z')ͳͲ΋
  23. <?php 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 $_; }
  24. 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 $_; }
  25. 12345678910

  26. ਖ਼نදݱϚονͱஔ׵ • Ϛον • if( "123" =~ /2/ ){ }

    • ஔ׵ • $abc =~ s/a/A/; • ݸਓతʹ͸݁ߏ޷͖ • ʮPerlه߸ଟਿʯ ʮperlopͰάάΕʯ
  27. <?php macro { T_VARIABLE·A =~ /T_STRING·B/ } >> { preg_match(

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

    'a' .'/u' ,$abc )){ echo 1; } # օ͞Μ͕͍͍͍ͨ͜ͱ͸ղΔ
  29. <?php 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;
  30. $abc =~ s/a/v/; // ↓ $abc = preg_replace( '/' .

    'a' . '/u', 'v' , $abc );
  31. ༨ஊ:JS෩ਖ਼نදݱϚον • if($abc./a/){ ... } • ʮOOPͬΆ͍ʂʯ ʮݩʑΦϒδΣΫτࢦ޲ݴޠ͔ͩͧͬ͠Γ͠Ζʯ • ʮPHPͳΒ

    −>Ͱ͸ʁʯ ʮͤ΍ͳʯ
  32. <?php 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; }
  33. if($abc./a/){ echo 1; } // ↓ if( preg_match( '/'. 'a'

    .'/u' , $abc ) ){ echo 1; }
  34. yadayada • ... • ʮޙͰ࣮૷͢Δ͔Β...ʯͱ͍͏࣌ͷʮ...ʯ • ౸ୡ͢Δͱɺྫ֎্͕͕Δ • //TODOΑΓ΋Θ͔Γ΍͍͢…͔΋…͠Εͳ͍

  35. <?php macro { ... } >> { throw new \Exception

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

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

  38. <?php macro { { ···body } } >> { (

    function( $arg ) { extract( $arg ); ···body } ) ( get_defined_vars() ) ; } $abc = 'abc'; { $abc = 'def'; echo $abc, PHP_EOL; } echo $abc, PHP_EOL;
  39. { $abc = 'def'; } // ↓ ( function( $arg·cfSNIPda

    ) { extract( $arg·cfSNIPda ); $abc = 'def'; } ) ( get_defined_vars() ) ;
  40. def abc

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

  42. <?php 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;
  43. use \This\Is\Test; // ↓ use \This\Is\Test ; __require( '\This\Is\Test' )

    ;
  44. use strict; use warnings; • ͍ܰΤϥʔͰ΋ऴྃ͢Δ • ͋΍͍͠ॴͰܯࠂ͢Δ • ʢຊ౰͸΋͏ͪΐͬͱҙຯ͕͋Δʣ

    • ʢηοτ͍ͯ͠ΔΤϥʔϋϯυϥ࡞๏͸ݸਓతझ ຯͰ͢ʣ
  45. <?php 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;
  46. use strict; use warnings; // ↓ <?php set_error_handler( function( $errno·cfSNIPda,

    $errstr·cfSNIPda, $errfile·cfSNIPda, $errline·cfSNIPda ){ throw new \Error($errstr·cfSNIPda); } ); error_reporting(-1);
  47. ·ͱΊ • yayͬͯ݁ߏศརͰ͸ʂʢʁʣ • ʮҰਓϓϩδΣΫτ΍झຯͳΒͳʂʯ • ஔ׵ͱ͔Ͱ͸ͳ͍ͷͰɺ ʢͪΌΜͱॻ͚͹ʣ͔ͳΓյΕͮΒ͍ • ग़ྗ͞ΕΔͷ͸ɺຊ౰ͷPHPͳͷͰ҆৺ʢʁʣ

    • ୯७ͳϧʔλʔఆٛͷDSLͳΒͭ͘Ε·ͨ͠
  48. ຊ౰ʹ΍Δਓ΁ͷίϝϯτ • yayɺυΩϡϝϯτ͕ςετίʔυ͔͠ͳ͍ͷͰௐ ΂Δͷ͕େม • τʔΫϯछͷT_VARIABLE౳͸ github/nikic/PHP-Parser • ύʔαʔͷ·ls౳͸ github/marcioAlmada/yay/src/

    parsers.php • ʮͱʹ͔࣮͘૷ͱςετίʔυΛݟΔΜͩʯ
  49. • ·ͱ.ͱɾΛؒҧ͑ͯେม • middle dot • ʮ·(00B7)ͬͯɺීஈͲ͏΍ͬͯೖྗ͢ΔΜ΍…ʯ • ʮதࠇΛ·(00B7)ʹม׵͢Δpreprocessor͕ඞཁͰ ͸ʯ

  50. __END__

  51. __halt_compiler();

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

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

  54. <?php macro { (···condition) -> { ···body } } >>

    { function ( ···condition ) { ···body } } $a = ($v)->{ echo $v; }; $a('abc');
  55. $a = ($v)->{ echo $v; }; // ↓ $a =

    function ( $v ) { echo $v; };
  56. Defined-Or, //= ԋࢉࢠ • $a //= 'default'; • ʢ//͸??ͱಉ͡ʣ •

    ຊؾͰཉ͍͠ • 7.xͰདྷΔʢ͚ͲઌऔΓͱ͍͏͜ͱͰʣ => https://wiki.php.net/rfc/ null_coalesce_equal_operator
  57. <?php macro { T_VARIABLE·A ??= } >> { T_VARIABLE·A =

    T_VARIABLE·A ?? } $a ??= 123; echo $a;
  58. $a ??= 123; echo $a; // ↓ $a = $a

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

  60. <?php macro { split } >> { mb_split } macro

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