# 機能設計書 106-findx

## 概要

本ドキュメントは、Hack Standard Library（HSL）の `C\findx` 関数の機能設計書である。この関数は、Traversableの中から述語を満たす最初の値を取得し、見つからない場合は例外をスローする。

### 本機能の処理概要

`C\findx` 関数は、与えられた `Traversable` の要素を順番に調べ、指定された述語関数が `true` を返す最初の要素を返す関数である。条件を満たす要素が見つからない場合は `InvariantException` をスローする（`x` は「exception」を表す）。

**業務上の目的・背景**：条件を満たす要素が必ず存在することがビジネスロジック上保証される場合、null チェックを省略してコードを簡潔にすることができる。例えば、システム設定でデフォルト値が必ず存在する場合や、検証済みデータからの検索など、要素が見つからないことが異常事態である場合に使用される。例外をスローすることで、想定外の状況を早期に検出できる。

**機能の利用シーン**：
- 必ず存在するはずのデフォルト設定を取得する場合
- 検証済みのデータセットから特定の要素を取得する場合
- IDで検索した結果が必ず見つかることが保証される場合
- ビジネスルール上、該当要素が存在しないことがエラーである場合
- null チェックを避けて型安全なコードを書きたい場合

**主要な処理内容**：
1. 入力パラメータとして Traversable と述語関数を受け取る
2. Traversable の各要素に対してループ処理
3. 各要素に述語を適用
4. 述語が true を返す最初の要素を返す（ショートサーキット）
5. 条件を満たす要素がない場合は InvariantException をスロー

**関連システム・外部連携**：なし（純粋な関数であり、外部システムへの依存はない）

**権限による制御**：なし（ライブラリ関数のため権限制御は不要）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | 本プロジェクトはUIを持たないライブラリのため画面は存在しない |

## 機能種別

検索処理 / 選択処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | Traversable<T> | Yes | 検索対象のTraversable | なし |
| $value_predicate | (function(T)[_]: bool) | Yes | 各要素に適用する述語関数 | bool を返す必要あり |

### 入力データソース

関数呼び出し元から引数として渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | T | 条件を満たす最初の値（非null保証） |

### 出力先

関数の戻り値として呼び出し元に返される。

## 処理フロー

### 処理シーケンス

```
1. Traversable と述語関数を引数として受け取る
   └─ 述語は必須パラメータ
2. Traversable の各要素に対してループ処理
   └─ foreach で順次処理
3. 各要素に述語を適用
   └─ 述語が true を返した場合、その要素を即座に返す（ショートサーキット）
4. ループが終了しても条件を満たす要素がない場合
   └─ invariant_violation で InvariantException をスロー
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[traversable, predicate を受け取る]
    B --> C[foreach ループ開始]
    C --> D{次の要素あり?}
    D -->|Yes| E[要素に predicate を適用]
    E --> F{結果が true?}
    F -->|Yes| G[その要素を返す]
    F -->|No| C
    D -->|No| H[InvariantException をスロー]
    G --> I[終了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-106-01 | 最初の一致を返す | 複数の要素が条件を満たす場合、最初に見つかった要素のみを返す | 常に適用 |
| BR-106-02 | ショートサーキット | 条件を満たす要素が見つかった時点で処理を終了 | 要素が条件を満たした場合 |
| BR-106-03 | 例外スロー | 条件を満たす要素がない場合は InvariantException をスロー | 要素が見つからない場合 |
| BR-106-04 | 非null戻り値 | 戻り値は必ず非null値（T型） | 常に適用 |

### 計算ロジック

特になし（検索処理のみで複雑な計算処理は含まれない）

## データベース操作仕様

該当なし（本機能はインメモリのコレクション操作のみを行う）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvariantException | 実行時例外 | 条件を満たす要素が見つからない場合 | try-catch で捕捉するか、事前に C\find で存在確認 |
| TypeError | 型エラー | 述語が bool を返さない場合 | 型チェッカーがコンパイル時に検出 |

### リトライ仕様

該当なし（同期処理であり、リトライの必要性はない）

## トランザクション仕様

該当なし（データベース操作を行わない純粋関数）

## パフォーマンス要件

- 時間計算量: O(n) - 最悪の場合、全要素をチェック
- 空間計算量: O(1)
- ショートサーキット評価により、条件を満たす要素が見つかった時点で処理終了

## セキュリティ考慮事項

- 純粋関数であり、外部への副作用がないためセキュリティリスクは低い
- 述語関数は呼び出し元から渡されるため、述語内での副作用には注意が必要
- 例外メッセージに機密情報が含まれないよう注意

## 備考

- 関数名の末尾の `x` は例外（exception）を表す HSL の命名規則
- 要素が見つからない可能性がある場合は `C\find` を使用する
- エラーメッセージは "Couldn't find target value." 固定
- 関連関数: `C\find`（null許容版）、`C\find_key`（キー取得版）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

本関数で扱うデータ構造は、Hack言語の組み込み型である `Traversable` である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | (Hack組み込み型) | - | Traversable<T> は foreach で反復可能な全ての型の基底インターフェース |

**読解のコツ**: 戻り値が `T`（非null）であることに注目。`C\find` の `?T` とは異なり、必ず値を返すか例外をスローする。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.php | `src/c/select.php` | C\findx 関数の定義を確認 |

**主要処理フロー**:
1. **36-44行目**: 関数のドキュメントコメント
2. **43行目**: `C\find()` への参照（null許容版）
3. **45-55行目**: `findx` 関数の定義
4. **49-52行目**: foreach ループで各要素をチェック
5. **50-52行目**: 述語が true を返したら即座にその値を返す
6. **54行目**: 見つからなかった場合は invariant_violation で例外スロー

#### Step 3: 関連関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.php | `src/c/select.php` | 比較: C\find 関数との違い |

**主要処理フロー**:
- **24-34行目**: `C\find` 関数 - null許容版（比較用）
- **33行目**: find は見つからない場合 null を返す
- **54行目**: findx は見つからない場合 invariant_violation

### プログラム呼び出し階層図

```
C\findx($traversable, $value_predicate)
    │
    ├─ $value_predicate($value)  [ユーザー指定の述語関数]
    │
    └─ invariant_violation()  [見つからない場合]
           │
           └─ throw InvariantException
```

### データフロー図

```
[入力]                       [処理]                           [出力]

Traversable<T> ───┐
                  ├──▶ foreach + predicate適用 ──▶ T (値) or Exception
predicate ────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.php | `src/c/select.php` | ソース | C\findx 関数の実装（45-55行目） |
| CSelectTest.php | `tests/c/CSelectTest.php` | テスト | findx のユニットテスト（47-83行目） |
