# 機能設計書 78-shuffle

## 概要

本ドキュメントは、Hack Standard Library（HSL）のVec名前空間が提供する`shuffle`関数の機能設計を記述する。この関数は、Traversableの要素をランダムに並べ替えた新しいvecを生成する機能を提供する。

### 本機能の処理概要

`Vec\shuffle`関数は、入力されたTraversableの要素をランダムな順序で並べ替えた新しいvecを返却する。PHPの組み込み関数`shuffle`を内部で使用しており、暗号学的に安全ではないランダム化を行う。

**業務上の目的・背景**：データのランダム化は、テストデータの生成、ゲームロジック、サンプリング、A/Bテストなど多くの場面で必要となる。`shuffle`関数は、このようなランダム化処理を簡潔に実行することを可能にする。ただし、暗号学的に安全なランダム化が必要な場合は、SecureRandom名前空間の関数を使用する必要がある。

**機能の利用シーン**：
- クイズやゲームで選択肢をランダムに並べ替える
- テストデータをランダムな順序で処理する
- サンプリングやシャッフル操作を行う
- デモ用データのランダム表示

**主要な処理内容**：
1. 入力としてTraversableを受け取る
2. Traversableをvecに変換する
3. PHPのshuffle関数でランダムに並べ替える
4. ランダム化されたvecを返却する

**関連システム・外部連携**：本機能は純粋な関数であり、外部システムとの連携はない。内部でPHPの組み込み関数\shuffleを使用する。

**権限による制御**：本機能は`leak_safe`コンテキストで動作する。これは、関数が外部に情報を漏洩しない（純粋ではないが安全）ことを示す。

## 関連画面

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

## 機能種別

計算処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | Traversable<Tv> | Yes | ランダム化する対象のコレクション | なし（空コレクションも許容） |

### 入力データソース

関数引数として直接渡される。Traversableとして許容される型には、vec、dict、keyset、Vector、Map、Set、およびカスタムIteratorが含まれる。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vec<Tv> | 要素がランダムに並べ替えられた新しいvec |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. Traversableをvecに変換
   └─ $vec = cast_clear_legacy_array_mark($traversable)
2. PHPのshuffle関数でインプレースにランダム化
   └─ \shuffle(inout $vec)
3. ランダム化されたvecを返却
   └─ return $vec
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[$traversableをvecに変換]
    B --> C[PHPのshuffle関数を呼び出し]
    C --> D[ランダム化された$vecを返却]
    D --> E[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-78-01 | ランダム順序 | 要素はランダムな順序に並べ替えられる | 常時 |
| BR-78-02 | 要素保持 | すべての要素が保持される（追加も削除もされない） | 常時 |
| BR-78-03 | 空入力処理 | 空のTraversableは空のvecを返す | 入力が空の場合 |
| BR-78-04 | キー破棄 | KeyedTraversableのキーは破棄される | KeyedTraversable入力時 |
| BR-78-05 | 非暗号学的 | 暗号学的に安全なランダム化ではない | 常時 |
| BR-78-06 | 非破壊操作 | 入力のTraversableは変更されない | 常時 |

### 計算ロジック

PHPの\shuffle関数に依存する。Fisher-Yatesアルゴリズムに基づくランダム化が行われる。

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

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数は例外をスローしない | - |

### リトライ仕様

本機能にリトライ仕様はない。

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

本機能はデータベーストランザクションを使用しない。

## パフォーマンス要件

- 時間計算量: O(n) - nは入力要素数
- 空間計算量: O(n) - 結果格納用のvec

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

**重要**: この関数は暗号学的に安全なランダム化を提供しない。セキュリティが重要な用途（例：トークン生成、認証キー生成など）には使用しないこと。そのような用途にはSecureRandom名前空間の関数を使用すること。

## 備考

- 暗号学的に安全なランダム化が必要な場合はSecureRandom名前空間を使用する
- 内部関数`cast_clear_legacy_array_mark`を使用してレガシー配列マークをクリアする
- コンテキスト`[leak_safe]`は、副作用はあるが情報漏洩しないことを示す

---

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

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

### 推奨読解順序

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

`shuffle`関数はシンプルなvec操作を行う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Hack言語組み込み型 | - | Traversable<Tv>とvec<Tv>の関係を理解する |

**読解のコツ**: `inout`パラメータはHack固有の参照渡しを示す。PHPの\shuffleはinoutでvecを受け取り、インプレースで並べ替えを行う。

#### Step 2: 補助関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cast.php | `src/vec/cast.php` | cast_clear_legacy_array_mark関数の実装を確認 |
| 2-2 | PHPの\shuffle | PHP組み込み関数 | インプレースでランダム化を行う関数 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | order.php | `src/vec/order.php` | shuffle関数の定義と実装を確認 |

**主要処理フロー**:
1. **67-69行目**: 関数シグネチャ - Traversableを受け取り、leak_safeコンテキストで動作
2. **70行目**: cast_clear_legacy_array_markでvecに変換
3. **71行目**: PHPの\shuffle関数をinoutで呼び出し
4. **72行目**: 結果を返却

#### Step 4: テストケースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | VecOrderTest.php | `tests/vec/VecOrderTest.php` | shuffle関数のテストケースを確認 |

**主要処理フロー**:
- **120-132行目**: provideTestShuffleメソッドでテストデータを提供
- **134-158行目**: testShuffleメソッド
- **138-144行目**: シャッフル後もソートすると元の順序になることを検証
- **146-155行目**: 1000回のシャッフルで少なくとも1回は異なる結果になることを検証

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

```
呼び出し元コード
    │
    └─ Vec\shuffle($traversable)
           │
           ├─ cast_clear_legacy_array_mark($traversable) → $vec
           │
           └─ \shuffle(inout $vec)（PHP組み込み関数）
                  │
                  └─ インプレースでランダム化
```

### データフロー図

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

Traversable<Tv>            ───▶  vecに変換
                                      │
                                      ▼
                                 \shuffle()          ───▶  vec<Tv>
                                 ランダム化                 (ランダム順)

例:
vec[1, 2, 3, 4, 5]         ───▶  shuffle処理  ───▶  vec[3, 1, 5, 2, 4]（例）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| order.php | `src/vec/order.php` | ソース | shuffle関数の実装 |
| cast.php | `src/vec/cast.php` | ソース | cast_clear_legacy_array_mark関数の実装 |
| VecOrderTest.php | `tests/vec/VecOrderTest.php` | テスト | shuffle関数のユニットテスト |
