やあ。Hackの世界へようこそ。君が今PHPからHackへ足を踏み入れようとしているなら、それは「曖昧さとの決別」を意味する素晴らしい決断だ。
今日は、Hackの流儀における最も基本的かつ強力な武器の一つ、「プロパティ昇格(Property Promotion)」について語ろう。PHPの冗長なコードを、Hackの厳格かつエレガントな構文へと昇華させる旅だ。準備はいいかい?
—
1. なぜ「PHP的」な書き方はHackでは「負債」なのか
PHPでクラスを書くとき、私たちはよくこんな書き方をしてきたはずだ。
// 古き良き(しかし冗長な)PHPのスタイル
class User {
private string $name;
private int $age;
public function __construct(string $name, int $age) {
$this->name = $name; // 代入作業の繰り返し
$this->age = $age; // 型宣言と代入が分離している
}
}
これの何が問題か?
1. DRY原則への違反: プロパティ名と型を2回記述しなければならない。
2. 保守コスト: コンストラクタに引数を追加するたびに、プロパティ宣言と代入の両方を修正する必要がある。
3. HHVMの最適化: 厳格な型システムを持つHackにおいて、この「宣言と代入の分離」は、HHVMの型推論エンジンに対して余計なヒントを要求するようなものだ。
—
2. Hackの極意:プロパティ昇格
Hackでは、コンストラクタの引数リストにアクセス修飾子(`public`, `private`, `protected`)を置くだけで、プロパティの宣言・初期化が完了する。これがプロパティ昇格だ。
<<__ConsistentConstruct>>
final class User {
// コンストラクタ内で宣言と初期化を完結させる
public function __construct(
private string $name,
private int $age,
) {}
}
これがコードに何をもたらすか
- 物理的なコード量の削減: 記述が半分になる。
- 型安全性: コンストラクタが呼ばれた瞬間にプロパティの型が確定するため、HHVMは最適化の段階で「このクラスは初期化漏れを起こさない」と断定できる。これは実行時のパフォーマンス向上に直結するんだ。
—
3. 陥りやすい罠:ここだけは注意してくれ
「簡単そうに見えて、実は深い」のがHackの型システムだ。初心者がよくやるミスを伝授しておく。
① 可視性の指定忘れ
`public`, `private` などを忘れると、それはただの「引数」として扱われる。プロパティとしてインスタンスに保持させたいなら、必ず修飾子をつけること。
② 初期化の不整合(nullableの罠)
もしプロパティを `?string`(nullable)にするなら、デフォルト値の扱いを意識しなければならない。
// 良い例:デフォルト値を持つ
public function __construct(
private string $name = “Unknown”,
) {}
③ インターフェースとの不整合
Hackではインターフェースとクラスの関係も厳格だ。もしインターフェースでプロパティを要求しているなら、実装クラス側でプロパティ昇格を使う際、型が完璧に一致しているかを確認してくれ。ここがズレていると、型チェッカー(`hh_client`)は容赦なく君を止めるはずだ。
—
4. 視覚的イメージで理解する
内部的には、HHVMは君の書いたコードを以下のように「展開」して処理していると考えていい。
[プロパティ昇格]
↓ (HHVMのコンパイル時)
[展開された構造]
- フィールド領域の確保 (メモリ配置)
- コンストラクタ引数のコピー代入
- 型ガード (型が合わない場合の早期終了)
君が数行の昇格コードを書くとき、HHVMは舞台裏で「メモリレイアウトの最適化」と「型安全性の検証」という重い作業を瞬時に完遂しているんだ。君はただ、簡潔に書くだけでいい。
—
最後に:Hackを掌握する君へ
プロパティ昇格は、単なるシンタックスシュガーではない。「型安全性」と「保守性」を両立させるための、言語設計者からの贈り物なんだ。
まずは、今書いているPHPのクラスを一つ選んで、この昇格構文に書き換えてみてほしい。`hh_client` が何も文句を言わず「No errors!」と表示したとき、君はHackの厳格な心地よさを肌で感じるはずだ。
もし何か行き詰まったら、いつでも質問してくれ。Hackの道は険しいが、その先に見える景色は、PHPの世界とは比較にならないほど澄み渡っているよ。
さあ、次はどのコードを「昇格」させる?