Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
HHVM/Hackで得る問題解決力 / hhvm-hack-problem-solving
Search
yuuki takezawa
September 04, 2018
Technology
3
2.2k
HHVM/Hackで得る問題解決力 / hhvm-hack-problem-solving
builderscon 2018 tokyo の資料です
yuuki takezawa
September 04, 2018
Tweet
Share
More Decks by yuuki takezawa
See All by yuuki takezawa
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
100
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
250
再考 アクターモデル/ reconsider actor model
ytake
0
1k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
410
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
250
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.1k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
770
技術的負債と向き合う取り組みでよかったもの / positive_efforts_to_tackle_technical_debt
ytake
10
3.8k
アプリケーションエンジニアから強いデータエンジニアへの歩き方 / How to transition and become a Data Engineer from an Application Engineer
ytake
1
550
Other Decks in Technology
See All in Technology
「海外登壇」という 選択肢を与えるために 〜Gophers EX
logica0419
0
700
オブザーバビリティの観点でみるAWS / AWS from observability perspective
ymotongpoo
8
1.5k
開発組織のための セキュアコーディング研修の始め方
flatt_security
3
2.4k
Classmethod AI Talks(CATs) #17 司会進行スライド(2025.02.19) / classmethod-ai-talks-aka-cats_moderator-slides_vol17_2025-02-19
shinyaa31
0
120
Platform Engineeringは自由のめまい
nwiizo
4
2.1k
N=1から解き明かすAWS ソリューションアーキテクトの魅力
kiiwami
0
130
TAMとre:Capセキュリティ編 〜拡張脅威検出デモを添えて〜
fujiihda
2
240
ユーザーストーリーマッピングから始めるアジャイルチームと並走するQA / Starting QA with User Story Mapping
katawara
0
200
『衛星データ利用の方々にとって近いようで触れる機会のなさそうな小話 ~ 衛星搭載ソフトウェアと衛星運用ソフトウェア (実物) を動かしながらわいわいする編 ~』 @日本衛星データコミニティ勉強会
meltingrabbit
0
140
なぜ私は自分が使わないサービスを作るのか? / Why would I create a service that I would not use?
aiandrox
0
730
OpenID Connect for Identity Assurance の概要と翻訳版のご紹介 / 20250219-BizDay17-OIDC4IDA-Intro
oidfj
0
270
Moved to https://speakerdeck.com/toshihue/presales-engineer-career-bridging-tech-biz-ja
toshihue
2
740
Featured
See All Featured
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Docker and Python
trallard
44
3.3k
Become a Pro
speakerdeck
PRO
26
5.1k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
630
How to Ace a Technical Interview
jacobian
276
23k
4 Signs Your Business is Dying
shpigford
182
22k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
Rails Girls Zürich Keynote
gr2m
94
13k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
366
25k
Optimizing for Happiness
mojombo
376
70k
Transcript
HHVM/HackͰಘΔղܾྗ yuuki takezawa builderscon 2018
Profile • ᖒ ༗و / ytake • גࣜձࣾΞΠελΠϧ CTO •
PHP, Hack, Go, Scala • Apache Hadoop, Apache Spark, Apache Kafka
ͱΓ͋͛Δ͜ͱ • ༷ʑͳղܾ • HackʹΑΔղܾ • ΞϓϦέʔγϣϯʹ͓͚Δղܾ
ղܾͱ • Λղܾ͢Δɺ ͢ͳΘͪղΛൃݟ͢Δ͜ͱͰ͋Γɺ ࢥߟͷҰ෦Ͱ͋Δ • νʔϜʹ͓͚ΔࢥߟͰ͋ͬͨΓ ΦϒδΣΫτࢦͰ͋ͬͨΓ
ͳͥHackΛ͏ͷ͔
എܠ • શମతʹPHPϝΠϯͷٕज़ελοΫ • WebΞϓϦέʔγϣϯ͕ϝΠϯ • GoͷΞϓϦέʔγϣϯ͍͔ͭ͘ • ੳॲཧScala͕͍͔ͭ͘
ݒ೦ • ͦΕ XX ͰͰ͖ΔΑ • ಛఆͷݴޠ͔͠Βͳ͍ • ։ൃͱ͍͏ߦҝʹΫϦΤΠςΟϒ͕͞ײ͡ΒΕͳ͍
બͷύϥυοΫε https://www.ted.com/talks/barry_schwartz_on_the_paradox_of_choice?language=ja
None
None
ΞϓϦέʔγϣϯ ϦϦʔε͢Δ·ͰͰͳ͘ɺ ϦϦʔε͔ͯ͠Β͕ຊ൪
։ൃऀ ΞϓϦέʔγϣϯͱͱʹ ͢Δ
None
։ൃͷଊ͑ํ • ͍ͭͷࢹͱগ͠ҧ͏ࢹΛՃͯ͠ΈΔ • ҧ͏ࢹͷ͋ͱɺ͍ͭͷݴޠ͔Β • ํʹಇ͘ݟ͑ํΛཆ͏͜ͱѱ͍͜ͱʁ • ͍ͭͷࢹ͚ͩɺѱ͍͜ͱʁ
None
None
ࢹΛม͑Δํ๏ͷҰͭͱͯ͠ HackΛར༻
PHP͕ ͪΐͬͱૣ͘ͳͬͨͭͰ͠ΐʁ
HHVM/Hack • ݴޠͷϕʔεʹ͋ΔͷPHPͷվળ • I/O͕ൃੜ͢Δͷʹରͯ͠ͷAsync/Await શͯʹରͯ͠࡞༻͢ΔΘ͚Ͱͳ͍ͷͰɺෑډ͕͍ • ݫ֨ͳܕνΣοΫͱίϨΫγϣϯɾ੬ऑੑରࡦ
for Developer • Atom + Nuclide • Visual Studio Code
+ Hack plugin • Docker (hhvm/hhvm)
.hhconfig
.hhconfig ͷجຊ • HackͰ࣮ߦڥʹઃஔ͢ΔϑΝΠϧ • ༷ʑͳઃఆΛهड़Ͱ͖Δ • PHPར༻Λఆ͠ͳ͍(PHPࠞࡏෆՄ) assume_php
= false(default: true) • Type Checker Ұ෦ແࢹ ignored_paths = [ "vendor/hhvm/hhast/.+" ]
.hhconfig ͋Ε͜Ε • λΠϓνΣοΧʔͷϝϞϦૢ࡞ • ࢀর͠͏ͳϞʔυՃ(3.28) disallow_return_by_ref disallow_array_cell_pass_by_ref
None
ۤ࿑ • IDEʹ͓͚Δิػೳͷಈ͖ • Τϥʔ༰͕Θ͔Βͳ͍ • PHPʹݟ͍͑ͯͯผͱ͍͏ೝࣝΛͭ·Ͱ • ใऩूྗ
Type Checker
None
Type Checker • ίϯύΠϥϥΠΫʹಈ͘ܕνΣοΫπʔϧ • Ϟʔυ3ͭ Partial / Strict /
Decl • σϑΥϧτͰPartial
Type Checker: Partial • PHPͷܕએݴ strictͱಉఔ • ඞཁҎ্ʹܕνΣοΫ͠ͳ͍ • ओʹPHPͷίʔυΛ
Hackͱ࣮ͯ͠ߦ͢Δ ίʔυҠ২தͷϑΝΠϧͰར༻ • ࢀর͠ ར༻Մೳ
Type Checker: Decl • <?hh // decl • ܕνΣοΫ͠ͳ͍ •
ଞͷίʔυνΣοΫ࣌ʹࢀর͞ΕΔ • New Hack code should never be written in decl mode
Type Checker: Strict • <?hh // strict • PHPґଘ͕ͳ͘ɺ100% HackͰ࣮͢Δ߹ʹબ
• ݫ֨ͳܕνΣοΫΛߦ͏ϞʔυͷͨΊɺ ίʔυϨϏϡʔ࣌ͷܕએݴʹ͍ͭͯͷٞඞཁ࠷খݶ • ఆ֎ͷܕมͳͲߦΘΕͳ͍ͨΊɺ ϨϏϡʔΫϥεઃܭɾΞʔΩςΫνϟͳͲʹ ϑΥʔΧεͰ͖Δ
for Example • ίϯετϥΫλͰॳظԽ͍ͯ͠ͳ͍ίʔυܯࠂ • isset͡Όͳͯ͘ɺarray_key_existsΛ͍ͳ͍͞ • ͨͩͷarray͡ΌΘ͔Βͳ͍ Vector͔Map͍ͳ͍͞
ߟ͑ํΛม͑Δ • ͱΓ͋͑ͣarray ͦͷarrayͲΜͳׂ͕͋ΓɺͲ͏͍͏ͷͳͷ͔ • arrayͰ͋Δඞཁ͕͋Δͷ͔Ͳ͏͔
Hackͷarrayࡾछྨ • array ௨ৗͷྻ • varray ͷΈͰߏ͞ΕΔྻ • darray σΟΫγϣφϦͷྻ
<?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; } } ܕҧ͍ Γܕҧ͍ Γܕҧ͍
ΞϓϦέʔγϣϯʹ͓͚Δ ղܾ
None
ܧঝΛ੍ޚ͢Δ • Sealed Class • Sealed Interface • Hack 3.27
Ҏ߱
<<__Sealed(Hoge::class)>> class SealedClass { } <<__Sealed(Sample::class)>> interface SealedInterface { }
ࢦఆͨ͠ΫϥεҎ֎ ܧঝෆՄ ࢦఆͨ͠ΫϥεҎ֎ ܧঝෆՄɾ࣮ෆՄ
ܧঝʹ͍ͭͯͷߟ͑ํ • final classͷΈͰ੍(ڐՄ)Λ͔͚Δ͔ • GenericsͰදݱͷΈڐՄ͢Δͷ͔ • ͦͷޙͷΞϓϦέʔγϣϯͷͱɺ ֦ுੑͰେ͖͘Ξϓϩʔν͕ҟͳΔ
ܕม
public function sum(): int { return 10 + "5e2"; }
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.
ܕม: mixed
public function get($id): mixed { return //Կ͔Λฦ٫͢Δ; } $container =
new Container(); $container->get('something');
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͚ʹهड़
final class Util { public function something(mixed $any): mixed {
if($any is int) { // } if($any is string) { // } } }
Type Constants
interface TypeInterface { abstract const type T; public function getNative():
this::T; }
class UserType implements TypeInterface { const type T = Vector<int>;
public function getNative(): this::T { return new Vector([1,2]); } }
Factory
class Sample { }
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ͳͲ
<<__ConsistentConstruct>> class Sample { } constructor੍ޚ
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จࣈྻࢦఆ ࣮֬ͳΠϯελϯεੜ
ࣝผͷҧ͍
final class BookId { private $id; public function __construct(string $id)
{ $this->id = $id; } public function getValue(): string { return $this->id; } }
final class BookId { public function __construct( private string $id
) {} public function getValue(): string { return $this->id; } }
ҧ͏දݱํ๏
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
ॻ੶දݱํ๏
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; } // লུ }
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; } // লུ } ݎ੍͍ ݎ੍͍
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) }
ॻ੶ίϨΫγϣϯදݱํ๏
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; } } ϑΟʔϧυ੍ͳ͠
type BookShape = shape( 'book_id' => string, 'title' => string,
'price' => int ); ϑΟʔϧυ੍
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
$v = new Vector([ new Book('1234', 'testing', 2999), new Book('1235',
'testing', 2999), ]); $v = $v->filter( ($t) ==> $t->getId() === '1234' )->immutable(); collection filter Πϛϡʔλϒϧʹ
ෳҙຯΛ࣋ͨͤͳ͍ͨΊͷ੍ޚ • ߹ͷ͍͍ΫϥεΛ࡞Βͳ͍ • ूΛΑΓߟ͑Δ • ͳΜͰͰ͖ΔΫϥεͰͳ͍ ͜Ε͔͠Ͱ͖ͳ͍Ϋϥε
ݫ֨ͳܕΛPHPΞϓϦέʔγϣϯʹద༻͢Δҙຯ • ͱΓ͋͑ͣಈ͘ঢ়ଶʹͰ͖Ε͍͍ • ༷มߋ͕͋Εܕ͕ͳ͍ํ͕ଟ༷ੑ͋ΔΜ͡Όͳ͍ʁ • ͦͦଞͷݴޠͰΑ͘ͳ͍ʁ
ͱΓ͋͑ͣಈ͘ঢ়ଶ͔Β ៉ྷʹ͢Δ࣌ؒͳ͔ͳ͔དྷͳ͍
None
બࢶͱࢹΛ͛Δ
Λղܾ͢Δɺ ͢ͳΘͪղΛൃݟ͢Δ͜ͱͰ͋Γɺ ࢥߟͷҰ෦
ղܾ͢ΔͨΊͷྗͱ ࢹ