# 機能設計書 19-Comparableモジュール

## 概要

本ドキュメントは、mrubyにおけるComparableモジュールの機能設計を記述する。Comparableモジュールは比較演算子（<=>）に基づく比較メソッド群を提供するミックスインモジュールである。

### 本機能の処理概要

Comparableモジュールは、`<=>`演算子（宇宙船演算子）を基盤として、`<`, `<=`, `==`, `>`, `>=`, `between?`の比較メソッドを自動的に提供する。ISO 15.3.3に準拠する。このモジュールをインクルードするクラスは`<=>`メソッドのみを定義すれば、全ての比較メソッドが自動的に利用可能になる。String、Numeric等のコアクラスがこのモジュールをインクルードしている。

**業務上の目的・背景**：比較操作は並べ替え、範囲判定、条件分岐など多くの処理で使用される基本的な機能である。各クラスが個別に全比較メソッドを実装するのではなく、`<=>`演算子のみの実装でリッチな比較機能を得られるようにすることで、コードの重複を排除し、一貫した比較セマンティクスを保証する。

**機能の利用シーン**：数値の大小比較、文字列の辞書順比較、日付の前後判定、カスタムオブジェクトの並べ替え、範囲内判定（between?）等。

**主要な処理内容**：
1. `<` - 小なり比較
2. `<=` - 以下比較
3. `==` - 等値比較
4. `>` - 大なり比較
5. `>=` - 以上比較
6. `between?` - 範囲内判定

**関連システム・外部連携**：String、Numeric等のコアクラスにインクルードされる。Enumerableのsort/max/minメソッドが暗黙的に依存する。

**権限による制御**：なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIベースのランタイム機能のため関連画面なし |

## 機能種別

計算処理 / 比較

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| other | Object | Yes | 比較対象 | <=>がnilを返す場合はArgumentError |
| min | Object | Yes（between?） | 範囲の下限値 | なし |
| max | Object | Yes（between?） | 範囲の上限値 | なし |

### 入力データソース

インクルード先クラスの`<=>`メソッドの戻り値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 真偽値 | Boolean | 全比較メソッドの判定結果（true/false） |

### 出力先

呼び出し元への戻り値として返却。

## 処理フロー

### 処理シーケンス

```
1. 比較メソッド呼び出し
   └─ self <=> other を呼び出し
   └─ 結果がnilの場合: ArgumentError（==を除く）
   └─ 結果を閾値と比較して真偽値を返却
       ├─ <  : cmp < 0
       ├─ <= : cmp <= 0
       ├─ == : cmp.equal?(0)
       ├─ >  : cmp > 0
       ├─ >= : cmp >= 0
       └─ between?(min,max): self >= min and self <= max
```

### フローチャート

```mermaid
flowchart TD
    A[比較メソッド呼び出し] --> B["cmp = self <=> other"]
    B --> C{cmp == nil?}
    C -->|Yes, ==以外| D[ArgumentError]
    C -->|Yes, ==の場合| E[false を返す]
    C -->|No| F{メソッド種別}
    F -->|<| G["cmp < 0 ?"]
    F -->|<=| H["cmp <= 0 ?"]
    F -->|==| I["cmp.equal?(0) ?"]
    F -->|>| J["cmp > 0 ?"]
    F -->|>=| K["cmp >= 0 ?"]
    G --> L[true/false 返却]
    H --> L
    I --> L
    J --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-19-01 | <=>必須 | Comparableをインクルードするクラスは<=>メソッドを定義する必要がある | 常時 |
| BR-19-02 | nil処理（==以外） | <=>がnilを返した場合、<, <=, >, >=はArgumentErrorを発生 | <=>がnil時 |
| BR-19-03 | nil処理（==） | <=>がnilを返した場合、==はfalseを返す（エラーにならない） | ==呼び出し時 |
| BR-19-04 | between? | between?(min, max)は self >= min and self <= max | between?呼び出し時 |
| BR-19-05 | <=>の戻り値規約 | -1（小さい）、0（等しい）、1（大きい）、nil（比較不能） | <=>実装時 |

### 計算ロジック

- **==の実装**: `cmp.equal?(0)` - `equal?`を使用しているため、`cmp`が整数0のときのみtrueを返す（`0.0 == 0`とは異なる挙動）

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

該当なし（インメモリ操作のみ）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentError | <=>がnilを返し、<, <=, >, >=が呼ばれた場合 | <=>を正しく実装する |
| - | NoMethodError | <=>が未定義のクラスでComparableメソッドを呼び出し | <=>を実装する |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- 各比較メソッドは<=>を1回呼び出すのみ（between?は2回）
- <=>の実装に依存した計算量

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

- 特になし

## 備考

- ISO 15.3.3に準拠
- 純粋なRuby実装（C実装なし）
- mrblib/compar.rbのみで完結

---

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

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

### 推奨読解順序

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

Comparableモジュールは特別なデータ構造を持たない。<=>演算子の戻り値（整数またはnil）のみを使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | compar.rb | `mrblib/compar.rb` | モジュール定義と全メソッドの実装 |

**読解のコツ**: Comparableは純粋なRuby実装であり、C側の実装は存在しない。全メソッドが`self <=> other`の呼び出し結果に基づいて判定を行うシンプルなパターンになっている。`==`だけが`cmp.equal?(0)`を使用しており、他のメソッドとはnilハンドリングが異なる点に注意。

#### Step 2: 各メソッドの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | compar.rb | `mrblib/compar.rb` | <, <=, ==, >, >=, between? の6メソッド |

**主要処理フロー**:
- **16-22行目**: `<` - cmpがnilでArgumentError、cmp < 0 で判定
- **33-39行目**: `<=` - cmpがnilでArgumentError、cmp <= 0 で判定
- **50-53行目**: `==` - cmp.equal?(0) で判定（nilの場合はfalse、ArgumentErrorなし）
- **64-70行目**: `>` - cmpがnilでArgumentError、cmp > 0 で判定
- **81-87行目**: `>=` - cmpがnilでArgumentError、cmp >= 0 で判定
- **99-101行目**: `between?` - self >= min and self <= max

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

```
Comparable メソッド呼び出し（<, <=, ==, >, >=）
    |
    +-- self <=> other
    |       |
    |       +-- インクルード先クラスの<=>実装
    |
    +-- nil チェック（==以外）
    |       |
    |       +-- nil → ArgumentError
    |
    +-- 結果判定（cmp < 0, cmp <= 0, etc.）

between?(min, max)
    |
    +-- self >= min (再帰的にComparable#>=を使用)
    |       |
    |       +-- self <=> min
    |
    +-- self <= max (再帰的にComparable#<=を使用)
            |
            +-- self <=> max
```

### データフロー図

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

self, other          self <=> other                    true / false
             ---->   結果（Integer or nil）       ---->
                       |
                     nil → ArgumentError（==以外）
                     Integer → 閾値比較
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| compar.rb | `mrblib/compar.rb` | ソース（Ruby） | Comparableモジュールの全実装（102行） |
| string.rb | `mrblib/string.rb` | ソース（Ruby） | StringクラスのComparableインクルード |
| numeric.rb | `mrblib/numeric.rb` | ソース（Ruby） | NumericクラスのComparableインクルード |
