PHPからHackへ:型安全を極める「プロパティ昇格」の真実
コードベースが肥大化する際、最もノイズとなるのは「宣言と代入の繰り返し」だ。PHPのクラス設計において、フィールドの定義、コンストラクタの引数、そして `this->x = $x` という儀式。あれは単なるボイラープレートではない。型安全を損なう温床であり、コンパイラの最適化パスを阻害する無駄な記述だ。
Hackにおける「プロパティ昇格(Property Promotion)」は、単なるシンタックスシュガーではない。HHVMの型チェッカー(HackC)がコードの意図をより深く解釈し、メモリレイアウトを最適化するための強力なフックである。
今回は、実務レベルのコードベースをHackへ移行する際、どのように「美しく、かつ強固な型定義」へと昇華させるかを伝授する。
—
1. PHPの「冗長な儀式」を解体する
まず、私たちが日々目にしている、修正すべき「負債」の典型例を見てみよう。
// PHPの典型的なアンチパターン
class UserSession {
private string $id;
private int $expiresAt;
public function __construct(string $id, int $expiresAt) {
$this->id = $id;
$this->expiresAt = $expiresAt;
}
}
このコードの何が悪いか?
1. DRY原則の違反: 変数名と型が2回登場し、修正時に同期ズレ(バグ)を生む。
2. 初期化漏れのリスク: `__construct` で代入し忘れるリスクを静的解析に頼りすぎている。
3. メタデータの冗長性: HHVMのVMレベルから見れば、コンストラクタのスタックフレームを消費するだけで、本質的な計算は何もしていない。
—
2. Hackのプロパティ昇格:アーキテクチャの最適化
Hackでは、コンストラクタ引数に修飾子をつけるだけで、フィールド定義と代入を一度に完結させる。
<<__ConsistentConstruct>>
final class UserSession {
// 昇格されたプロパティ。これだけでフィールド定義、初期化が完了する。
public function __construct(
private string $id,
private int $expiresAt,
) {}
public function isValid(): bool {
return HH\Lib\Math\abs($this->expiresAt) > HH\Lib\Time\time();
}
}
なぜこれが「最強」なのか?
- コンパイラによる強制保証: `private` などの修飾子を付与した時点で、HHVMはコンパイル時にクラスのメモリレイアウトを決定する。代入ミスという概念そのものが存在し得ない。
- HSL(Hack Standard Library)との親和性: `HSL` を用いた非同期API連携において、データクラスをこの形式で定義すれば、`Shape` や `KeyedContainer` との相互変換もシームレスに行える。
- パフォーマンス: プロパティ昇格を利用することで、HHVMのJITコンパイラはコンストラクタ内での不要なオペコード(代入命令)を排除し、直接レジスタへの割り当てを最適化できる余地が広がる。
—
3. 実務で「落ちないコード」を書くための設計パターン
単に記述を短くするだけではプロとは言えない。依存性の注入(DI)と非同期データフェッチが絡む実務環境では、以下のような「読み取り専用」の設計が推奨される。
namespace App\Model;
use HH\Lib\C;
final class ApiResult {
// Readonlyプロパティ昇格を利用して不変性を担保する
public function __construct(
public readonly string $requestId,
public readonly vec
) {}
// 不変データに対する堅牢なフィルタリング例
public function getActivePayload(): vec
return C\filter($this->payload, $item ==> $item !== ”);
}
}
意識すべきポイント
1. `readonly` の活用: 外部からの不用意な値の書き換えをコンパイル時に防ぐ。これは並列処理や非同期IOが絡むシステムでのバグを劇的に減らす。
2. `vec` や `dict` の使用: `array` という「何でも入るゴミ箱」を捨て、HSLのコレクション型に強制することで、実行時の型エラーを排除する。
3. `final` クラスの強制: 継承による予期せぬ挙動を遮断する。これはHackにおける堅牢なコンポーネント設計の鉄則だ。
—
最後に:コードは「書く」ものではなく「定義する」もの
PHPからHackへの移行は、単なる言語の乗り換えではない。「実行時に型を検証する」という怠惰な発想から、「コンパイル時に型を確定させる」というプロフェッショナルな設計への転換だ。
プロパティ昇格を利用したクラス設計は、あなたが書いたコードがHHVM上でどのように動作するかという「VMの呼吸」を感じ取る第一歩となる。ボイラープレートを削ぎ落とし、本質的なロジックに集中せよ。それが、システムを盤石にする唯一の道だ。
次のレビューでは、コンストラクタ内で `this->x = $x` を見かけたら、迷わず「昇格させろ」と一言添えてほしい。それが、君のコードベースを救うことになる。