【入門編】『Partial Mode』から『Strict Mode』への移行:段階的リファクタリングのロードマップ – Hack言語 コア・静的型システムとHHVMのアーキテクチャ解析バイブル

こんにちは!フルスタックエンジニアの先輩として、今日は皆さんと一緒にHack言語の最もエキサイティングで、かつ実務で一番頭を悩ませるポイントについて深く掘り下げていきたいと思います。

テーマは『Partial Mode』から『Strict Mode』への移行:段階的リファクタリングのロードマップです。

「既存のPHPコードベースをHackに置き換えていきたいけれど、最初からすべてを厳格モード(Strict Mode)にするのは無理ゲーに見える……」
そんな絶望感を抱いたことはありませんか?大丈夫です。世界最高峰のコードベースでも、移行はいつも泥臭い一歩から始まります。

今日は、HHVMの型チェッカーの挙動や、言語の重みを理解し尽くした私たちが、現場で使える現実的な移行戦略を優しく、そして徹底的に解説していきますね。ここをクリアすれば、あなたも立派なHackマスターの仲間入りです!

—

1. なぜ「Strict Mode」を目指すのか?(前提の共有)

Hack言語には、主に以下の2つのモードが存在します。

1. Partial Mode (`// partial`):
型推論や型チェックが「緩い」モード。型が指定されていない部分は `mixed` や `Any` のように扱われ、動的なPHPのノリをかなり許容します。
2. Strict Mode (`// strict`):
一切の妥協を許さない厳格な世界。すべての関数、メソッド、プロパティに型が必須であり、曖昧な型(`mixed`の安易な使用など)は厳しく弾かれます。

「じゃあ、ずっとPartialでいいじゃん」と思いますよね?
しかし、HHVM(HipHop Virtual Machine)の真価、そしてJITコンパイラの最適化の恩恵を100%引き出し、実行時エラー(TypeErrorなど)を完全にコンパイル時になくすためには、最終的にすべてのコードをStrict Modeにする必要があるのです。

Partial Modeは、あくまで「PHPからHackへの避難所(トランジション・エリア)」にすぎません。

—

2. 移行の全体像:段階的リファクタリングの4ステップ

いきなり全ファイルの先頭を `// strict` に書き換えるのは、爆弾処理の線を適当に切るようなものです。型チェッカーが数千のエラーを吐き出して心が折れてしまいます。

私たちが推奨する現実的なロードマップは以下の4ステップです。

[Step 1: 記述のHack化]
↓ (PHPからHack構文への置換)
[Step 2: Partial Modeでの生存]
↓ (HH_FIXMEや型注釈の導入)
[Step 3: 境界線の厳格化 (Strictify Leaves)]
↓ (末端のモジュールから Strict にしていく)
[Step 4: 完全なる Strict Mode 達成]

この「末端(Leaves)から中心(Core)へ向かってStrict化していく」アプローチが、現場で最も破綻しにくい黄金律となります。

—

3. 実践:PartialからStrictへの書き換えとよくある罠

具体的にコードをどう直していくのか、イメージしやすい例を見ていきましょう。

移行前:混沌としたPartial Modeのコード

まずは、典型的なPartial Modeのコードです。どこに型を入れればいいか曖昧ですね。

// partial
namespace MyApp;

class UserLoader {
// 引数も返り値も型がない(あるいは曖昧)
public function loadUser($id) {
$db = $this->getDbConnection();
$result = $db->query(“SELECT FROM users WHERE id = ” . $id);

if (!$result) {
return null; // 戻り値が ?array なのか ?User なのか曖昧
}

return $result;
}
}

このコードを Strict Mode に移行しようとすると、型チェッカー(hh_client)から次のようなお叱りを受けます。

> Type Error: In strict mode, you must specify a type on all methods and parameters.(厳格モードでは、すべてのメソッドとパラメータに型を指定しなければなりません)

移行後:美しく堅牢な Strict Mode のコード

これを Strict Mode に適合させた姿がこちらです。

// strict
namespace MyApp;

// データの構造を明確にするための形状(Shape)やクラス定義
type UserData = shape(
‘id’ => int,
‘name’ => string,
‘email’ => string,
);

class StrictUserLoader {

// 依存性注入を意識したコンストラクタ(型が完全に保証されている)
public function __construct(private IDatabaseConnection $db) {}

// すべてのパラメータと戻り値に厳格な型を付与
public function loadUser(int $id): ?UserData {
$result = $this->db->query(
“SELECT id, name, email FROM users WHERE id = %d”,
$id
);

if ($result->numRows() === 0) {
return null; // ?UserData の仕様通り null を返す
}

// データを正確にマッピングして返す
return shape(
‘id’ => (int)$result->row[‘id’],
‘name’ => (string)$result->row[‘name’],
‘email’ => (string)$result->row[‘email’],
);
}
}

—

4. 移行期に陥りやすい文法エラーと回避のテクニック

Strict Modeへ移行する際、開発者が必ずと言っていいほどハマる「落とし穴」があります。ここを知っておくだけで、無駄なデバッグ時間を何時間も節約できますよ。

落とし穴1: `mixed` の安易な使用とナローイング(Narrowing)

Partialから移行する際、型がわからないからと何でも `mixed` に逃げたくなるのですが、Strict Modeでは `mixed` 型のままプロパティにアクセスしたりメソッドを呼ぶことは許されません。

対策:
型チェッカーに「今この変数はこの型である」と教え込む(ナローイングする)必要があります。

// strict
function processData(mixed $input): string {
// ちゃんと型ガード(is_string など)を通す必要がある
if (string $input) { // Hackではis_stringやHH\is_stringを使用
return $input; // ここで $input は string型 にナローイングされる
}
throw new \InvalidArgumentException(“String required”);
}

落とし穴2: ヌラブル(Nullable)の扱い忘れ

PHPではうっかり `null` が入るようなプロパティを放置しがちですが、HackのStrict Modeは `null` の混入を許しません。許す場合は明示的に `?T`(Nullable)にする必要があります。

// エラーになる例
// int $age; // 初期化されていない、またはnullが入る可能性があるならNG

// 正しい書き方
private ?int $age = null;

—

5. 先輩からの実践アドバイス:HH_FIXMEの正しい使い所

「どうしても今のアーキテクチャの都合上、一時的に型エラーをスルーさせたい……!」
そんなときの裏技が、ハックの型チェッカーを一時的に黙らせるマジックコメント `/ HH_FIXME[エラーコード] /` です。

// strict
public function legacyIntegration(mixed $legacyData): void {
// レガシーな外部ライブラリがどうしても型エラーを吐く場合の緊急避難
/ HH_FIXME[4110] 外部ライブラリの型不一致を一時的に無視 /
$this->processLegacy($legacyData);
}

ただし、これはいわば「技術的負債の借用書」です。
コードベース全体をStrictにするロードマップの途中で `HH_FIXME` を多用しすぎると、後で回収不可能の沼にハマります。「FIXMEは書いたら必ずJira等のチケットを切り、1スプリント以内に解消する」というルールをチームで徹底してくださいね。

—

まとめ:ここをクリアすれば、Hackの基本はバッチリマスターできますよ!

いかがでしたでしょうか?

1. 末端(Leaves)のモジュール、影響範囲の小さいユーティリティクラスから Strict に書き換えていく
2. すべてのパラメータ、プロパティ、戻り値に妥協なく型を注釈する
3. `mixed` や `null` の扱いを厳密にコントロールする

このステップを地道に踏んでいくことで、あなたの書くコードベースは、HHVMのJIT最適化が最大限に効く、超高速で堅牢な要塞へと生まれ変わります。

最初はエラーの多さにめまいがするかもしれませんが、型チェッカーが赤く教えてくれるエラーは、あなたをより優れたエンジニアにしてくれる「優しいアラーム」です。一つひとつクリアしていきましょう。

あなたのHackライフが素晴らしいものになるよう、いつも応援しています!質問があればいつでも気軽に声をかけてくださいね。

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