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でアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
1.1k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
130
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
440
再考 アクターモデル/ reconsider actor model
ytake
0
1.1k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
440
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
280
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.1k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
810
技術的負債と向き合う取り組みでよかったもの / positive_efforts_to_tackle_technical_debt
ytake
10
3.8k
Other Decks in Technology
See All in Technology
AI・LLM事業部のSREとタスクの自動運転
shinyorke
PRO
0
300
TopAppBar Composableをカスタムする
hunachi
0
130
20250328_OpenAI製DeepResearchは既に一種のAGIだと思う話
doradora09
PRO
0
160
OCI見積もり入門セミナー
oracle4engineer
PRO
0
120
ルートユーザーの活用と管理を徹底的に深掘る
yuobayashi
6
730
バクラクでのSystem Risk Records導入による変化と改善の取り組み/Changes and Improvement Initiatives Resulting from the Implementation of System Risk Records
taddy_919
0
220
OPENLOGI Company Profile for engineer
hr01
1
22k
30 代子育て SRE が考える SRE ナレッジマネジメントの現在と将来
kworkdev
PRO
0
140
コンソールで学ぶ!AWS CodePipelineの機能とオプション
umekou
2
120
どっちの API SHOW?SharePoint 開発における SharePoint REST API Microsoft Graph API の違い / Which API show? Differences between Microsoft Graph API and SharePoint REST API
karamem0
0
110
日本MySQLユーザ会ができるまで / making MyNA
tmtms
1
370
ペアプログラミングにQAが加わった!職能を超えたモブプログラミングの事例と学び
tonionagauzzi
1
150
Featured
See All Featured
A better future with KSS
kneath
238
17k
Building an army of robots
kneath
304
45k
Raft: Consensus for Rubyists
vanstee
137
6.9k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
28
1.6k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
118
51k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
227
22k
KATA
mclloyd
29
14k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5.4k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
30
1.1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
102
18k
Optimizing for Happiness
mojombo
377
70k
Optimising Largest Contentful Paint
csswizardry
35
3.2k
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
બࢶͱࢹΛ͛Δ
Λղܾ͢Δɺ ͢ͳΘͪղΛൃݟ͢Δ͜ͱͰ͋Γɺ ࢥߟͷҰ෦
ղܾ͢ΔͨΊͷྗͱ ࢹ