# 機能設計書 13-Arrayクラス

## 概要

本ドキュメントは、mrubyにおけるArrayクラスの機能設計を記述する。Arrayクラスは配列の生成・追加・削除・検索・ソート・イテレーション等の配列操作全般を提供する組み込み型クラスである。

### 本機能の処理概要

Arrayクラスは、mrubyの中核となる動的配列型を実装する。ISO 15.2.12に準拠し、要素の追加・削除・アクセス・ソート・イテレーションなどの基本操作を提供する。内部的には埋め込み配列（小サイズ配列のオブジェクト内格納）とヒープ配列の2つのメモリ戦略を採用し、メモリ効率を最適化している。Enumerableモジュールをインクルードしており、collect、select、inject等の列挙操作も利用可能である。

**業務上の目的・背景**：配列はデータの格納・操作に最も頻繁に使用されるデータ構造であり、あらゆるプログラミング場面で不可欠である。組み込み環境では限られたメモリを効率的に使用する必要があるため、小さな配列はオブジェクト内に直接埋め込む最適化（MRB_ARY_EMBED_LEN_MAX要素以下）を行い、ヒープ割り当てのオーバーヘッドを削減している。また、共有配列（mrb_shared_array）によるcopy-on-writeメカニズムで不要なメモリコピーを回避している。

**機能の利用シーン**：データの一時格納、イテレーション処理、引数の受け渡し、メソッドの戻り値、Enumerableメソッドの結果格納など、mrubyプログラミングのあらゆる場面で使用される。VMのスタック操作においても内部的に使用される。

**主要な処理内容**：
1. 配列オブジェクトの生成とメモリ管理（埋め込み/ヒープ/共有）
2. 要素の追加（push, <<, unshift, concat）
3. 要素の削除（pop, shift, delete, clear）
4. 要素のアクセス（[], first, last）
5. 要素の設定（[]=, replace）
6. 要素の検索（include?, index）
7. ソート（sort, sort!）
8. イテレーション（each, each_index, collect!, map!）
9. 配列の結合（join, +, |, &）
10. 配列のサイズ管理（length, size, empty?, resize）

**関連システム・外部連携**：Enumerableモジュールをインクルードしており、map/select/inject等の列挙メソッドが利用可能。Rangeオブジェクトによるスライスアクセスも対応。

**権限による制御**：freezeされた配列への破壊的操作はFrozenErrorを発生させる。

## 関連画面

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

## 機能種別

データ操作 / コレクション管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| capa | Integer | No | 初期容量 | ARY_MAX_SIZE以下 |
| value | Object | No | 格納する要素 | なし |
| index | Integer | Yes（[]） | アクセスインデックス | 範囲外はnilを返す |
| block | Proc | No | イテレーション用ブロック | なし |

### 入力データソース

リテラル記法、C APIからの生成、他メソッドの戻り値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 配列 | Array | 新しい配列、またはselfの返却 |
| 要素 | Object | pop, shift, []等の取得結果 |
| 整数 | Integer | length, size, index等の数値結果 |
| 文字列 | String | join, inspect等の文字列結果 |
| 真偽値 | Boolean | include?, empty?等の判定結果 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 配列オブジェクトの生成
   └─ 容量チェック（ary_check_too_big）
   └─ メモリ戦略の決定
       ├─ 埋め込み（MRB_ARY_EMBED_LEN_MAX以下）: ARY_SET_EMBED_LEN
       └─ ヒープ: mrb_malloc でメモリ確保
2. 要素操作
   └─ 共有配列の場合: mrb_ary_modify() で排他化
   └─ 容量拡張が必要な場合: ary_expand_capa
   └─ 操作の実行
3. イテレーション
   └─ Rubyレベル: each, each_index, collect!, sort
   └─ Enumerableメソッド: map, select, inject等
```

### フローチャート

```mermaid
flowchart TD
    A[配列生成要求] --> B{要素数 <= EMBED_MAX?}
    B -->|Yes| C[埋め込み配列として格納]
    B -->|No| D[ヒープにメモリ確保]
    C --> E[RArray オブジェクト返却]
    D --> E
    E --> F{破壊的操作?}
    F -->|Yes| G{共有配列?}
    G -->|Yes| H[mrb_ary_modify で排他化]
    G -->|No| I{容量不足?}
    H --> I
    F -->|No| J[読み取り操作実行]
    I -->|Yes| K[ary_expand_capa で拡張]
    I -->|No| L[操作実行]
    K --> L
    J --> M[結果返却]
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-13-01 | 埋め込み最適化 | MRB_ARY_EMBED_LEN_MAX以下の配列はオブジェクト内に直接格納 | 配列生成時 |
| BR-13-02 | 最大サイズ制限 | MRB_ARY_LENGTH_MAX（デフォルト131072）を超える配列は生成不可 | 配列生成/拡張時 |
| BR-13-03 | 共有配列 | dupやslice時はcopy-on-writeで共有 | 配列コピー時 |
| BR-13-04 | 縮小比率 | 配列縮小時、容量が使用量のARY_SHRINK_RATIO（5）倍以上なら縮小 | 要素削除時 |
| BR-13-05 | デフォルト容量 | 初期容量はARY_DEFAULT_LEN（4）要素分 | new/空配列生成時 |
| BR-13-06 | Enumerable包含 | ArrayはEnumerableをインクルードする | 常時 |

### 計算ロジック

- **埋め込み判定**: `MRB_ARY_EMBED_LEN_MAX = sizeof(void*)*3/sizeof(mrb_value)`
- **最大サイズ**: `ARY_MAX_SIZE = min(ARY_C_MAX_SIZE, MRB_INT_MAX-1)`

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentError | 配列サイズがMRB_ARY_LENGTH_MAXを超える場合 | サイズを削減する |
| - | IndexError | 範囲外インデックスへのアクセス（一部メソッド） | インデックスを確認する |
| - | FrozenError | frozenな配列への破壊的操作 | 非frozen配列を使用する |
| - | TypeError | 非配列型との不正な操作 | 型を確認する |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- 小さな配列の埋め込みによるヒープ割り当ての回避
- 共有配列によるcopy-on-writeでメモリコピーを削減
- push/popのO(1)（償却）、insert/deleteのO(n)
- sortはRubyレベルでsort!に委譲（self.dup.sort!）

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

- メモリ境界チェックによるバッファオーバーフロー防止
- ary_check_too_bigによるサイズオーバーフロー検出

## 備考

- ISO 15.2.12に準拠
- deconstruct メソッドによるパターンマッチングサポート
- ARM環境でのmemcpy最適化問題への対策（array_copy関数）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | array.h | `include/mruby/array.h` | RArray構造体の定義、埋め込み/ヒープ/共有の管理マクロ |

**読解のコツ**: RArrayはRStringと同様に共用体で埋め込みとヒープを表現。flagsの下位3ビット（MRB_ARY_EMBED_MASK=7）で埋め込みかどうかを判定。ARY_EMBED_LEN(a)は`(flags & 7) - 1`で計算されるため、0の場合は非埋め込み。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | array.c | `src/array.c` | `mrb_init_array()`関数（2292行目）でクラス定義 |

**主要処理フロー**:
1. **2292-2302行目**: Arrayクラス定義、Array.[]クラスメソッド登録、ROMメソッドテーブル初期化

#### Step 3: メモリ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | array.c | `src/array.c` | 配列生成とメモリ管理関数群（17-96行目） |

**主要処理フロー**:
- **17-23行目**: 定数定義（ARY_DEFAULT_LEN=4, ARY_SHRINK_RATIO=5, MRB_ARY_LENGTH_MAX=131072）
- **26-30行目**: ary_too_big - サイズ超過エラー
- **33-42行目**: ary_check_too_big - サイズ検証
- **45-63行目**: ary_new_capa - 容量指定での配列生成（埋め込み/ヒープ判定あり）
- **76-81行目**: mrb_ary_new_capa - 公開API

#### Step 4: Rubyレベルメソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | array.rb | `mrblib/array.rb` | each, each_index, collect!, sort等のRuby実装 |

**主要処理フロー**:
- **15-24行目**: `each` - 基本的なイテレーション
- **35-44行目**: `each_index` - インデックスのイテレーション
- **56-66行目**: `collect!`/`map!` - 破壊的な要素変換
- **84-86行目**: `sort` - self.dup.sort!に委譲
- **94-96行目**: `deconstruct` - パターンマッチング対応
- **101行目**: `include Enumerable` 宣言

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

```
mrb_init_array()
    |
    +-- mrb_define_class_id(Array)
    +-- mrb_define_class_method_id([], mrb_ary_s_create)
    +-- MRB_MT_INIT_ROM(array_rom_entries)
            |
            +-- C実装メソッド群（push, pop, shift, unshift等）
            |       |
            |       +-- ary_new_capa (メモリ確保)
            |       +-- ary_expand_capa (容量拡張)
            |       +-- mrb_ary_modify (共有解除)
            |
            +-- mrblib/array.rb
                    |
                    +-- include Enumerable
                    +-- each, collect!, sort 等
```

### データフロー図

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

配列リテラル         ary_new_capa                        RArray オブジェクト
/要素列         ---->  (埋め込み or ヒープ)         ---->   (埋め込み or ヒープ)
                       |
操作要求         mrb_ary_modify (共有解除)          要素 / 新配列
(push等)    ---->  配列操作関数                ---->   / 整数 / 真偽値
                       |
                       +-- mrb_ary_push (追加)
                       +-- mrb_ary_pop (取り出し)
                       +-- mrb_ary_splice (部分置換)
                       +-- mrb_ary_join (結合)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| array.c | `src/array.c` | ソース（C） | Arrayクラスの主要実装（2303行） |
| array.rb | `mrblib/array.rb` | ソース（Ruby） | each, collect!, sort等のRuby実装 |
| array.h | `include/mruby/array.h` | ヘッダ | RArray構造体とC APIの宣言 |
| value_array.h | `src/value_array.h` | ヘッダ（内部） | 配列値コピーの内部ヘルパー |
| enum.rb | `mrblib/enum.rb` | ソース（Ruby） | Enumerableモジュール（Arrayがインクルード） |
