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

HHVM/Hackで得る問題解決力 / hhvm-hack-problem-solving

yuuki takezawa
September 04, 2018

HHVM/Hackで得る問題解決力 / hhvm-hack-problem-solving

builderscon 2018 tokyo の資料です

yuuki takezawa

September 04, 2018
Tweet

More Decks by yuuki takezawa

Other Decks in Technology

Transcript

  1. Profile • ஛ᖒ ༗و / ytake • גࣜձࣾΞΠελΠϧ CTO •

    PHP, Hack, Go, Scala • Apache Hadoop, Apache Spark, Apache Kafka

  2. for Developer • Atom + Nuclide • Visual Studio Code

    + Hack plugin • Docker (hhvm/hhvm)
  3. .hhconfig ͷجຊ • HackͰ࣮ߦ؀ڥʹઃஔ͢ΔϑΝΠϧ • ༷ʑͳઃఆΛهड़Ͱ͖Δ • PHPར༻Λ૝ఆ͠ͳ͍(PHPࠞࡏෆՄ) 
 assume_php

    = false(default: true)
 • Type Checker Ұ෦ແࢹ
 ignored_paths = [ "vendor/hhvm/hhast/.+" ]
  4. Type Checker: Partial • PHPͷܕએݴ strictͱಉఔ౓ • ඞཁҎ্ʹܕνΣοΫ͸͠ͳ͍ • ओʹPHPͷίʔυΛ

    Hackͱ࣮ͯ͠ߦ͢Δ
 ίʔυҠ২தͷϑΝΠϧ౳Ͱར༻ • ࢀর౉͠ ར༻Մೳ
  5. Type Checker: Decl • <?hh // decl • ܕνΣοΫ͸͠ͳ͍ •

    ଞͷίʔυνΣοΫ࣌ʹ͸ࢀর͞ΕΔ • New Hack code should never be written 
 in decl mode
  6. Type Checker: Strict • <?hh // strict • PHPґଘ͕ͳ͘ɺ100% HackͰ࣮૷͢Δ৔߹ʹબ୒

    • ݫ֨ͳܕνΣοΫΛߦ͏ϞʔυͷͨΊɺ
 ίʔυϨϏϡʔ࣌ͷܕએݴʹ͍ͭͯͷٞ࿦͸ඞཁ࠷খݶ • ૝ఆ֎ͷܕม׵ͳͲ͸ߦΘΕͳ͍ͨΊɺ
 ϨϏϡʔ͸ΫϥεઃܭɾΞʔΩςΫνϟͳͲʹ
 ϑΥʔΧεͰ͖Δ
  7. <?hh // strict class Sample { protected varray<string> $varray =

    varray[ 'php', 'hack' ]; protected darray<int, string> $darray = darray[ 'testing' => 'testing', 1 => 'testing' ]; public function failedVArray(): varray<int> { return $this->varray; } public function getDArray(): darray<string, string> { return $this->darray; } } ܕҧ͍ ໭Γܕҧ͍ ໭Γܕҧ͍
  8. <<__Sealed(Hoge::class)>> class SealedClass { } <<__Sealed(Sample::class)>> interface SealedInterface { }

    ࢦఆͨ͠ΫϥεҎ֎ ܧঝෆՄ ࢦఆͨ͠ΫϥεҎ֎ ܧঝෆՄɾ࣮૷ෆՄ
  9. public function sum(): int { return 10 + "5e2"; }

    Typing error This is a num (int/float) because this is used in an arithmetic operation. It is incompatible with a string.
  10. private function invariantLoggerInterface( Container $container, ): LoggerInterface { $logger =

    $container ->get(LoggerInterface::class); invariant( $logger instanceof LoggerInterface, "Interface '\Psr\Log\LoggerInterface' is not implemented by this class", ); return $logger; } mixedͷ৔߹͸Կ͕ฦ٫͞ΕΔ͔Θ͔Βͳ͍ ظ଴஋ͷ΋ͷ͕ฦ٫͞ΕΔ͔Ͳ͏͔ ඞͣهड़ͯ͠ɺTypeChecker޲͚ʹهड़
  11. final class Util { public function something(mixed $any): mixed {

    if($any is int) { // } if($any is string) { // } } }
  12. class UserType implements TypeInterface { const type T = Vector<int>;

    public function getNative(): this::T { return new Vector([1,2]); } }
  13. final class Factory { protected array $array = [ 'Sample'

    => Sample::class ]; public function get(string $id) { $key = \ucfirst(\strtolower($id)); if(\array_key_exists($key, $this->array)) { $class = $this->array[$key]; return new $class(); } } } class_existsͳͲ΋
  14. final class Factory { protected Map<string, classname<Sample>> $map = Map{

    'Sample' => Sample::class }; public function get(string $id): Sample { $class = $this->map->get(\ucfirst(\strtolower($id))); if (!\is_null($class)) { return new $class(); } throw new \RuntimeException(); } } classจࣈྻࢦఆ ࣮֬ͳΠϯελϯεੜ੒
  15. final class BookId { private $id; public function __construct(string $id)

    { $this->id = $id; } public function getValue(): string { return $this->id; } }
  16. final class BookId { public function __construct( private string $id

    ) {} public function getValue(): string { return $this->id; } }
  17. abstract class Identifier<T> { public function __construct( protected T $id

    ) {} public function getValue(): T { return $this->id; } } final class BookId<T> extends Identifier<T> { } Generics
  18. class Book { private $id; private $title; private $price; public

    function __construct( BookId $id, BookTitle $title, Price $price ) { $this->id = $id; $this->title = $title; $this->price = $price; } public function getId(): BookId { return $this->id; } // লུ }
  19. class Book { public function __construct( private BookId<string> $id, private

    BookTitle<string> $title, private Price<int> $price ) {} public function getId(): BookId<string> { return $this->id; } // লུ } ݎ੍͍໿ ݎ੍͍໿
  20. object(Book)#2 (3) { ["id":"Book":private]=> object(BookId)#3 (1) { ["id":protected]=> string(36) "6ad4bb95-262c-4a5b-a6c7-ac9b5cadf707"

    } ["title":"Book":private]=> string(18) "HHVM/Hack Practice" ["price":"Book":private]=> int(2999) }
  21. class BookCollection { protected $books = []; public function __construct(array

    $books = []) { $this->books = $books; } public function toArray(): array { $books = []; foreach($this->books as $book) { $books[] = new Book( new BookId($book['id']), new BookTitle($book['title']), new Price($book['price']) ); } return $books; } } ϑΟʔϧυ੍໿ͳ͠
  22. class BookCollection { protected Vector<Book> $v = Vector{ }; public

    function __construct( protected varray<BookShape> $array ) { $this->v = $this->vec(); } protected function vec(): Vector<Book> { $v = Vector{ }; foreach($this->array as $row) { $v->add(new Book( new BookId($row['book_id']), new BookTitle($row['title']), new Price($row['price']) )); } return $v; } public function toArray(): varray<Book> { return $this->v->toVArray(); } } shapeΛvarrayͰ to Vector
  23. $v = new Vector([ new Book('1234', 'testing', 2999), new Book('1235',

    'testing', 2999), ]); $v = $v->filter( ($t) ==> $t->getId() === '1234' )->immutable(); collection filter Πϛϡʔλϒϧʹ