# 機能設計書 12-Stringクラス

## 概要

本ドキュメントは、mrubyにおけるStringクラスの機能設計を記述する。Stringクラスは文字列の生成・連結・分割・検索・置換・エンコーディング処理等の文字列操作全般を提供する組み込み型クラスである。

### 本機能の処理概要

Stringクラスは、mrubyの中核となる文字列型を実装するクラスであり、ISO 15.2.10に準拠する。文字列データのメモリ管理（埋め込み文字列・ヒープ文字列・共有文字列）から、文字列の連結、分割、検索、置換、比較、変換などの豊富な操作を提供する。C APIとRubyレベルのメソッドの両方で利用可能であり、mrubyランタイムの基盤を構成する重要なクラスである。

**業務上の目的・背景**：文字列処理はプログラミングの最も基本的な機能の一つであり、ユーザ入力の処理、データのフォーマット、出力の生成など、あらゆる場面で不可欠である。組み込み環境ではメモリが限られるため、短い文字列の埋め込み最適化（RSTRING_EMBED_LEN_MAX以下の文字列をオブジェクト内に直接格納）や共有文字列（copy-on-write）によるメモリ効率の最適化が重要となる。

**機能の利用シーン**：テキストデータの操作全般。文字列リテラルの使用、文字列の連結（+, concat, <<）、部分文字列の抽出（[], slice）、パターンによる検索・置換（index, gsub, sub）、文字列の分割（split）、大文字小文字変換（upcase, downcase）、フォーマット変換（to_i, to_f, to_sym）等。

**主要な処理内容**：
1. 文字列オブジェクトの生成とメモリ管理（埋め込み/ヒープ/共有/nofree）
2. 文字列の連結（concat, +, <<）
3. 文字列の比較（==, <=>, casecmp）
4. 部分文字列の抽出とインデックスアクセス（[], slice, byteslice）
5. 文字列の検索（index, include?）
6. 文字列の置換（gsub, sub, replace）
7. 文字列の分割（split, each_line）
8. 大文字小文字変換（upcase, downcase, capitalize, swapcase）
9. 空白除去（strip, lstrip, rstrip, chomp, chop）
10. 型変換（to_i, to_f, to_sym, intern）
11. UTF-8エンコーディングサポート（オプション）

**関連システム・外部連携**：Comparableモジュールをインクルードしており、<=>演算子に基づく比較メソッドが利用可能。Symbol変換（to_sym）でシンボルテーブルと連携する。

**権限による制御**：freezeされた文字列への変更操作はFrozenErrorを発生させる。

## 関連画面

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

## 機能種別

データ操作 / 型変換 / 文字列処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| str | String | Yes | 操作対象の文字列 | MRB_STR_LENGTH_MAXを超える場合はArgumentError |
| pattern | String | Yes（gsub/sub） | 検索・置換パターン | なし |
| replacement | String | No（gsub/sub） | 置換文字列 | なし |
| separator | String | No（split/each_line） | 区切り文字 | なし |
| index | Integer | Yes（[]） | アクセス位置 | 範囲外はnilを返す |

### 入力データソース

文字列リテラル、他オブジェクトのto_s変換結果、C APIからの文字列生成。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 新文字列 | String | 連結・変換・抽出結果の新しい文字列オブジェクト |
| 配列 | Array | split等の分割結果 |
| 整数 | Integer | index, length, bytesize等の数値結果 |
| シンボル | Symbol | to_sym/internの変換結果 |
| 真偽値 | Boolean | include?, empty?, start_with?等の判定結果 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 文字列オブジェクトの生成
   └─ 長さチェック（str_check_length）
   └─ メモリ戦略の決定
       ├─ 埋め込み（RSTRING_EMBED_LEN_MAX以下）: str_init_embed
       ├─ ヒープ: str_init_normal / str_init_normal_capa
       ├─ nofree: str_init_nofree
       └─ 共有: str_init_shared / str_init_fshared
2. メソッド呼び出し
   └─ 破壊的メソッドの場合: mrb_str_modify() で共有解除
   └─ 処理の実行
   └─ 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[文字列生成要求] --> B{長さ <= EMBED_MAX?}
    B -->|Yes| C[埋め込み文字列として格納]
    B -->|No| D[ヒープ領域にメモリ確保]
    C --> E[RString オブジェクト返却]
    D --> E
    E --> F{破壊的操作?}
    F -->|Yes| G[mrb_str_modify で排他化]
    G --> H[文字列操作実行]
    F -->|No| H
    H --> I[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-12-01 | 埋め込み最適化 | RSTRING_EMBED_LEN_MAX以下の文字列はオブジェクト内に直接格納 | 文字列生成時 |
| BR-12-02 | 共有文字列 | 文字列のコピー時はcopy-on-write方式で共有 | dup/clone等 |
| BR-12-03 | 凍結保護 | frozenな文字列への破壊的操作はFrozenErrorを発生 | 破壊的メソッド呼び出し時 |
| BR-12-04 | 長さ制限 | MRB_STR_LENGTH_MAX（デフォルト1048576）を超える文字列はエラー | 文字列生成/拡張時 |
| BR-12-05 | Comparable包含 | StringはComparableをインクルードし、<=>による比較メソッドを提供 | 常時 |

### 計算ロジック

- **埋め込み判定**: `RSTRING_EMBED_LEN_MAX = sizeof(void*) * 3 + sizeof(void*) - 32/CHAR_BIT - 1`
- **文字列比較**: `mrb_str_cmp` によるバイト単位の辞書順比較

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentError | 負または最大値を超える文字列サイズ | サイズを修正する |
| - | ArgumentError | MRB_STR_LENGTH_MAXを超える文字列 | 文字列を短くする |
| - | FrozenError | frozenな文字列への破壊的操作 | 非frozenの文字列を使用する |
| - | TypeError | 非String型への文字列操作 | 型を確認する |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- 短い文字列はオブジェクト内に埋め込むことでヒープ割り当てを回避
- 共有文字列によるcopy-on-writeで不要なメモリコピーを削減
- ASCII文字列フラグ（MRB_STR_SINGLE_BYTE）による高速なインデックスアクセス

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

- NULL文字を含む文字列は`mrb_str_to_cstr`でArgumentErrorを発生
- メモリ境界チェックによるバッファオーバーフロー防止

## 備考

- ISO 15.2.10に準拠
- MRB_UTF8_STRING定義時はUTF-8マルチバイト文字列をサポート
- mrb_shared_string構造体による参照カウント付き共有メカニズム

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: RStringは共用体（union）を使って埋め込み文字列とヒープ文字列を同じメモリ領域で表現している。flags フィールドのビットマスクでタイプを識別する（MRB_STR_EMBED=8, MRB_STR_SHARED=1等）。RSTR_PTR/RSTR_LENマクロで埋め込み・ヒープを透過的にアクセスできる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | string.c | `src/string.c` | `mrb_init_string()`関数（3564行目）でクラス定義とメソッド登録 |

**主要処理フロー**:
1. **3564-3577行目**: Stringクラスの定義、メソッドテーブルのROM初期化

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | string.c | `src/string.c` | 文字列初期化関数群（67-100行目） |

**主要処理フロー**:
- **22-26行目**: mrb_shared_string構造体（参照カウント付き共有文字列）
- **40-51行目**: str_check_length - 文字列長の検証
- **67-80行目**: str_init_normal_capa - ヒープ文字列の初期化
- **88-97行目**: str_init_embed - 埋め込み文字列の初期化
- **99-100行目**: str_init_nofree - GC解放不要な文字列の初期化

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | string.rb | `mrblib/string.rb` | gsub, sub, each_line, each_byte等のRuby実装 |

**主要処理フロー**:
- **7行目**: `include Comparable` 宣言
- **14-43行目**: `each_line` - 行単位のイテレーション
- **52-78行目**: `gsub` - パターン置換
- **112-133行目**: `sub` - 最初のパターン置換
- **151-159行目**: `each_byte` - バイト単位のイテレーション

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

```
mrb_init_string()
    |
    +-- mrb_define_class_id(String)
    +-- MRB_MT_INIT_ROM(string_rom_entries)
    |       |
    |       +-- C実装メソッド群（concat, index, split等）
    |
    +-- mrblib/string.rb
            |
            +-- include Comparable
            +-- each_line, gsub, sub, each_byte 等
```

### データフロー図

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

文字列リテラル       str_init_embed/normal               RString オブジェクト
/C文字列        ---->  (メモリ戦略決定)           ---->   (埋め込み or ヒープ)
                       |
操作要求         mrb_str_modify (共有解除)          新文字列 / 配列
(gsub等)    ---->  文字列操作関数             ---->   / 整数 / 真偽値
                       |
                       +-- mrb_str_concat (連結)
                       +-- mrb_str_index (検索)
                       +-- mrb_str_substr (部分取得)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| string.c | `src/string.c` | ソース（C） | Stringクラスの主要実装（3578行） |
| string.rb | `mrblib/string.rb` | ソース（Ruby） | gsub, sub, each_line等のRuby実装 |
| string.h | `include/mruby/string.h` | ヘッダ | RString構造体とC APIの宣言 |
| compar.rb | `mrblib/compar.rb` | ソース（Ruby） | Comparableモジュール（Stringがインクルード） |
