【入門編】HHVMの『Type Checker』が検知する『Unsafe』なコードのパターンと修正フロー – Hack言語 コア・静的型システムとHHVMのアーキテクチャ解析バイブル

こんにちは!フルスタックエンジニアの先輩として、今日はHack言語の核心であり、最大の武器でもある「Strict Mode(厳格モード)」と型チェッカーの挙動について、ディープかつ分かりやすく解説していきますね。

他の言語(PHPやJavaScriptなど)からHackの世界に入ってきたとき、最初にぶつかる壁がこの型チェッカーからの「お叱り」です。でも安心してください。型チェッカーが怒る理由は、あなたのコードをいじめるためではなく、「将来のバグや本番障害という名のモンスターからあなたを守るため」なのです。

ここをクリアすれば、Hackの基本はバッチリマスターできますよ!それでは、HHVMの頭脳である型チェackerの思考回路を一緒に覗いていきましょう。

—

1. なぜHackの型チェッカーは「Unsafe」を許さないのか?

Hackは、動的言語であるPHPの血を引き継ぎながらも、その上に完全な静的型システムを構築した言語です。HHVM(HipHop Virtual Machine)の上で実行される際、Hackのコードは事前にミリ秒単位で型チェッカー(`hh_client`)によって解析されます。

型チェッカーが目指す究極のゴールは一つ。
「Runtime Error(実行時エラー)を、開発時のCompile Error(コンパイル時エラー)で駆逐する」ことです。

そのため、型が曖昧なコードや、実行時まで型が確定しない「Unsafe」な状態を見つけると、型チェッカーは容赦なくエラーを投げます。まずは、よくある3つの「アンチパターン」と、それをStrict Modeで美しく昇華させる修正フローを見ていきましょう。

—

2. 陥りやすい「Unsafe」な3つのパターンと修正フロー

パターンA:曖昧な型(`mixed` や動的プロパティ)の放置

他の言語ではよく見かける「とりあえず何でも入る変数」ですが、HackのStrict Modeではご法度です。

❌ アンチパターン:型が曖昧なコード

<<__Strict>>
namespace HackGuide\Patterns;

// 型が不明な入力をそのまま扱う危険な関数
function process_data(mixed $input): void {
// 警告・エラー:mixed型のままメソッドやプロパティにアクセスできません!
echo $input->toString();
}

何が問題なの?
`mixed`型は「何が入っているか分からない箱」です。中身が分からない状態であの手この手を使おうとすると、型チェッカーは「もし中身が文字列じゃなかったらクラッシュするよ!」とパニックを起こします。

⭕ 正しい修正フロー:型ガード(Type Narrowing)とパターンマッチ

Strict Modeでは、あらかじめ「これが何型であるか」を検証(ナローイング)してから使います。

<<__Strict>>
namespace HackGuide\Patterns;

function process_data(mixed $input): void {
// 1. 型を安全に判定する(型ガード)
if ($input is string) {
// このスコープの中では、$input は完全に string 型として扱われます!
echo “文字列です: “.$input;
} else if ($input is int) {
echo “整数です: “.(string)$input;
} else {
throw new \InvalidArgumentException(“サポートされていない型です”);
}
}

—

パターンB:NULLの可能性を無視したプロパティアクセス

データベースの検索結果など、「値があるかもしれないし、ないかもしれない(Nullable)」データを扱うときのエラーです。

❌ アンチパターン:NULLチェック抜きのメソッド呼び出し

class User {
public ?string $name = null;
}

function print_user_name(?User $user): void {
// エラー:$user自体が null の可能性があるので、->name にアクセスできません!
// さらに $user->name も ?string なので直接 echo できません!
echo $user->name;
}

⭕ 正しい修正フロー:Null安全オペレーターと早期リターン

Hackには、堅牢にNULLを扱うための構文が揃っています。ガード節(早期リターン)を使うのがスマートです。

<<__Strict>>
namespace HackGuide\Patterns;

class User {
public ?string $name = null;
}

function print_user_name(?User $user): void {
// 1. ガード節で null を弾く(これで以降、$user は確実に User インスタンスになる)
if ($user === null) {
echo “ユーザーが存在しません”;
return;
}

// 2. プロパティが null の場合のフォールバック(?? 演算子)を指定する
$name = $user->name ?? ‘名無しさん’;

echo “こんにちは、”.$name.”さん!”;
}

—

パターンC:コレクション(`Vector` や `Map`)の型抜け

Hackでは、配列の代わりに強力で型安全なコレクション(`vec`, `dict`, `keyset`)を使用します。ここに型を指定しない、あるいは混入させようとするとエラーになります。

❌ アンチパターン:PHP時代のノリで配列を雑に扱う

<<__Strict>>
namespace HackGuide\Patterns;

function calculate_total(vec $items): int {
$total = 0;
// vec の要素型が明示されていない場合(または旧式の array の場合)、
// 型チェッカーは要素が何であるか保証できません。
foreach ($items as $item) {
$total += $item;
}
return $total;
}

⭕ 正しい修正フロー:ジェネリクスによる型パラメータの明示

Hackのコレクションはジェネリクス(総称型)を使い、中に何が入るかを厳密に定義します。

<<__Strict>>
namespace HackGuide\Patterns;

// vec(整数のベクター)であることを完全に明示する
function calculate_total(vec $items): int {
$total = 0;
foreach ($items as $item) {
// $item は確実に int であることが保証されています
$total += $item;
}
return $total;
}

—

3. 現場で役立つ!型チェッカーと仲良くするための極意

最後に、実務でHackを書くときに意識してほしい「型チェッカーとの付き合い方」を3つ伝授します。

1. ファイル先頭の `<<__Strict>>` を恐れない
Hackファイルを新規作成したら、必ず最初に `<<__Strict>>` を宣言しましょう。最初は赤線(エラー)だらけになるかもしれませんが、それを一つずつ潰していくプロセスパズルこそが、Hackプログラミングの醍醐味です。
2. 推論に頼りすぎず、シグネチャ(引数・戻り値)を明記する
Hackの型チェッカーは非常に賢く、ローカル変数の型を自動推論(Type Inference)してくれます。しかし、関数の引数と戻り値だけは、サボらずに必ず型を書きましょう。コードの「仕様書」がコード自体に組み込まれるため、ドキュメントいらずの保守性の高いコードになります。
3. `hh_client` を常に手元で回す
IDEのプラグインやターミナルで `hh_client` を常時稼働させておき、コードを書いた瞬間にエラーがないかフィードバックを受ける環境を作りましょう。コンパイルを待つ必要すらない圧倒的なスピードで、あなたのコードが正しくビルドされていきます。

—

まとめ

いかがでしたでしょうか?
HackのStrict Modeと型チェッカーは、最初は厳しく感じるかもしれません。しかし、それは「動的言語の柔軟性を残したまま、静的言語の圧倒的な堅牢性を手に入れる」ための最高のパートナーです。

ここをマスターしたあなたなら、大規模で複雑なWebアプリケーションであっても、怖じ気づくことなくエレガントに設計・実装できるはずです。

それでは、素晴らしいHackライフを!分からないことがあったら、いつでも先輩に聞いてくださいね。

タイトルとURLをコピーしました