# 機能設計書 76-range

## 概要

本ドキュメントは、Hack Standard Library（HSL）のVec名前空間が提供する`range`関数の機能設計を記述する。この関数は、指定された開始値から終了値までの数値範囲を含むvecを生成する機能を提供する。

### 本機能の処理概要

`Vec\range`関数は、開始値、終了値、およびオプションのステップ値を受け取り、その範囲の数値を含むvecを生成する。開始値が終了値より大きい場合は、降順の範囲を生成する。整数と浮動小数点数の両方に対応している。

**業務上の目的・背景**：数値範囲の生成は、ループ処理、インデックス生成、テストデータ作成など多くの場面で必要となる。Pythonの`range()`やPHPの`range()`と同様の機能をHack言語で型安全に提供することで、開発者が簡潔に数値シーケンスを生成できるようにする。

**機能の利用シーン**：
- ループ処理用のインデックスシーケンスを生成する
- ページネーション用のページ番号リストを生成する
- テストデータとして連続した数値配列を作成する
- 数学的な計算のためのサンプルポイントを生成する

**主要な処理内容**：
1. 入力として開始値、終了値、オプションのステップ値を受け取る
2. ステップ値のデフォルト（1）を設定し、正の値であることを検証する
3. ステップが範囲より大きい場合は開始値のみを含むvecを返す
4. PHPの\range関数を使用して数値範囲を生成する
5. 結果をvecとして返却する

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

**権限による制御**：本機能は純粋関数（Pure Function）であり、権限による制御は適用されない。

## 関連画面

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

## 機能種別

計算処理 / データ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $start | Tv as num | Yes | 範囲の開始値（intまたはfloat） | なし |
| $end | Tv as num | Yes | 範囲の終了値（intまたはfloat） | なし |
| $step | ?Tv as num | No | ステップ値（デフォルト: 1） | 正の値であること（invariant） |

### 入力データソース

関数引数として直接渡される。`Tv as num`は、Tvがintまたはfloatのサブタイプであることを示す型制約である。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vec<Tv> | 指定された範囲の数値を含むvec |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. ステップ値の設定
   └─ $step ??= 1（nullの場合は1）
2. ステップ値の検証
   └─ invariant($step > 0, 'Expected positive step.')
3. ステップが範囲より大きい場合の処理
   └─ if ($step > Math\abs($end - $start)) return vec[$start]
4. PHPのrange関数を呼び出して範囲を生成
   └─ \range($start, $end, $step)
5. 結果をvecに変換して返却
   └─ return vec(\range($start, $end, $step))
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{$stepがnullか}
    B -->|Yes| C[$step = 1]
    B -->|No| D[$stepをそのまま使用]
    C --> E{$step > 0か}
    D --> E
    E -->|No| F[InvariantException: 正のステップが必要]
    E -->|Yes| G{$step > abs$end - $startか}
    G -->|Yes| H[vec$startを返却]
    G -->|No| I[PHPのrange関数を呼び出し]
    I --> J[結果をvecに変換]
    J --> K[vecを返却]
    H --> L[終了]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-76-01 | 正ステップ必須 | ステップ値は正の数でなければならない | 常時 |
| BR-76-02 | 降順対応 | $start > $endの場合は降順の範囲を生成 | $start > $endの場合 |
| BR-76-03 | 包含範囲 | 開始値と終了値の両方が含まれる | 終了値がステップで到達可能な場合 |
| BR-76-04 | ステップ超過 | ステップが範囲より大きい場合は開始値のみ | $step > abs($end - $start)の場合 |
| BR-76-05 | 型保持 | 入力型（intまたはfloat）が出力で保持される | 常時 |

### 計算ロジック

- 昇順の場合: $start, $start + $step, $start + 2*$step, ..., $end
- 降順の場合: $start, $start - $step, $start - 2*$step, ..., $end
- 要素数 = floor(abs($end - $start) / $step) + 1

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvariantException | $stepが0以下の場合 | 正のステップ値を指定する |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 時間計算量: O(n) - nは生成される要素数
- 空間計算量: O(n) - 結果格納用のvec

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

本機能は純粋関数であり、特別なセキュリティ考慮事項はない。非常に大きな範囲を指定するとメモリを大量に消費する可能性があるため、入力値の妥当性は呼び出し元で検証することを推奨する。

## 備考

- 繰り返し値が必要な場合は`Vec\fill`を使用する
- PHPの組み込み関数\rangeを内部で使用している
- floatを使用する場合は浮動小数点の精度に注意が必要

---

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

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

### 推奨読解順序

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

`range`関数は数値型（num）を扱う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Hack言語組み込み型 | - | `Tv as num`はTvがint|floatのサブタイプであることを示す型制約 |

**読解のコツ**: Hackの`as`制約は、ジェネリック型パラメータに上限を設定する。`Tv as num`は、Tvがnumまたはそのサブタイプ（intやfloat）であることを保証する。

#### Step 2: 依存関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Math\abs | HSL Math名前空間 | 絶対値関数を理解 |
| 2-2 | PHPの\range | PHP組み込み関数 | 範囲生成の基盤となる関数 |

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

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

**主要処理フロー**:
1. **26-30行目**: 関数シグネチャ - `Tv as num`の型制約
2. **31行目**: ステップのデフォルト値設定（null合体演算子）
3. **32行目**: ステップが正であることをinvariantで検証
4. **33-35行目**: ステップが範囲より大きい場合の処理
5. **36行目**: PHPのrange関数を呼び出して結果を返却

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

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

**主要処理フロー**:
- **17-62行目**: provideTestRangeメソッドで豊富なテストデータを提供
- **19行目**: 基本的な1から10までの範囲
- **21行目**: 明示的なステップ2
- **24行目**: 降順の範囲（10から1）
- **26-31行目**: 浮動小数点の範囲
- **51行目**: 同じ値の範囲（start == end）
- **54-60行目**: ステップが範囲より大きい場合
- **64-76行目**: テスト実行（toAlmostEqualで浮動小数点を比較）
- **78-93行目**: 例外ケースのテスト（ステップが0または負）

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

```
呼び出し元コード
    │
    └─ Vec\range($start, $end, $step)
           │
           ├─ $step ??= 1（デフォルト値設定）
           │
           ├─ invariant($step > 0, ...)（バリデーション）
           │
           ├─ Math\abs($end - $start)（範囲計算）
           │
           └─ \range($start, $end, $step)（PHP組み込み関数呼び出し）
                  │
                  └─ vec()（結果をvecに変換）
```

### データフロー図

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

$start: num          ───┐
                        │
$end: num           ───┼──▶  PHPのrange関数で     ───▶  vec<num>
                        │    数値シーケンスを生成
$step: ?num         ───┘

例:
$start=1, $end=5, $step=2  ───▶  range処理  ───▶  vec[1, 3, 5]
$start=10, $end=1, $step=3 ───▶  range処理  ───▶  vec[10, 7, 4, 1]
```

### 関連ファイル一覧

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