やあ。HHVMの深淵へようこそ。
コードベースが巨大化するにつれ、PHPの自由すぎる継承関係が「技術的負債」という名のモンスターへと変貌する瞬間を見たことはないかな?
「なぜこのクラスを継承してしまったんだ……」と頭を抱える夜を終わらせるために、今日はHackが誇る最強の守護者、`__Sealed` 属性と代数的データ構造(ADT)的アプローチについて語ろう。
—
PHPの「自由」は、時に「カオス」を呼ぶ
PHPでは、クラスを作れば誰でも、どこからでも `extends` ができてしまう。これが大規模開発では「継承ツリーの破壊」を招く。どこで誰が派生クラスを増やしたか追跡できず、`switch` 文や `if-else` での網羅性チェック(すべてのパターンを考慮しているか)が事実上不可能になるんだ。
Hackの `__Sealed` は、このカオスに「王の権限」で境界線を引くための強力な魔法だよ。
—
1. `__Sealed` で継承の門を閉ざす
`__Sealed` を使うと、「このインターフェース(またはクラス)を継承できるのは、私が許可したクラスだけだ」と明言できる。
<<__Sealed(Circle::class, Square::class)>>
interface Shape {
public function area(): float;
}
final class Circle implements Shape {
public function __construct(private float $radius) {}
public function area(): float => M_PI $this->radius 2;
}
final class Square implements Shape {
public function __construct(private float $side) {}
public function area(): float => $this->side $this->side;
}
// もしここで Triangle を作って implements Shape しようとすると…
// Hackの型チェッカーが “Triangle is not allowed to extend sealed interface Shape” と叱ってくれる。
見ての通り、このコードは「Shapeには円と正方形しかない」という事実を、型チェッカーに強制的に理解させているんだ。
—
2. 網羅性チェック(Exhaustive Matching)の恩恵
ここが一番美味しいところだ。`__Sealed` を使うと、HHVMの型チェッカーは「すべてのケースが網羅されているか」を静的に判定してくれる。
function getArea(Shape $shape): float {
// Shape が Sealed なので、以下の match 式で網羅性が担保される
return match ($shape) {
is Circle => $shape->area(),
is Square => $shape->area(),
// もしここで Square のケースを書き忘れると、
// Hackは「Non-exhaustive match: Square is not handled」とエラーを吐く。
};
}
この「網羅性チェック」があれば、将来的に `Triangle` を追加したくなった時、コンパイラが「お前、新しいShapeを追加したな? 対応するロジックも全部修正しろよ」と教えてくれるんだ。これぞ、大規模開発における究極の安心感だと思わないか?
—
3. よくある「罠」と解決策
罠その1:`final` を忘れるな
`__Sealed` なインターフェースを実装するクラスは、基本的には `final` にすべきだ。もし `final` を忘れると、その派生クラスがさらに継承されてしまい、意図しない継承階層が生まれてしまう。
罠その2:型の絞り込み(Type Refinement)の勘違い
たまに「`is` 演算子を使わずに `instanceof` で書きたい」という人がいるが、Hackでは `match` 式と `is` 演算子の組み合わせが最も堅牢だ。`instanceof` は実行時のチェックだが、`is` は型チェッカーと密に連携して型を絞り込んでくれる。
—
なぜこれが「伝説級」の設計なのか
この設計は、関数型言語でいう「代数的データ構造(Sum Types)」の概念を、オブジェクト指向のHackに持ち込んだものなんだ。
- PHP流: 全てがオープン。どこでバグが起きるか分からない。
- Hack流: 境界を封印(Sealed)し、全てのパターンを網羅(Exhaustive)する。
このアプローチを採用することで、君の書くコードは「動けば良い」という段階から「壊しようがない」という極限の堅牢性へと進化する。
—
さあ、次は君の番だ
まずは既存のインターフェースに `<<__Sealed(...)>>` を一つ付けてみることから始めてみてほしい。最初は型チェッカーがうるさく感じるかもしれないが、それは君のコードをバグから守ろうと必死になっている証拠だ。
ここをクリアすれば、もう君は「Hackの型システムを飼い慣らす側」の人間だ。何か躓いたら、いつでも聞いてくれ。HHVMの深層から、いつでもアドバイスを送るよ。
Happy Hacking!