# 機能設計書 42-Kernel拡張

## 概要

本ドキュメントは、mruby-kernel-ext gemが提供するKernelモジュールへの拡張メソッド群の機能設計を記述する。バックトレース取得、メソッド名取得、型変換関数（Integer, Float, String, Array, Hash）を追加する。

### 本機能の処理概要

mruby-kernel-ext gemは、Rubyプログラミングで頻繁に使用される関数的メソッドをKernelモジュールに追加する。全てC言語(src/kernel.c)で実装されており、プライベートメソッドとして登録される。

**業務上の目的・背景**：Rubyではグローバル関数として利用される型変換メソッド（Integer(), Float(), String(), Array(), Hash()）やデバッグ用メソッド（caller, __method__, __callee__）は標準的なプログラミングパターンの一部である。mrubyコアには含まれないこれらのメソッドを拡張gemとして提供する。

**機能の利用シーン**：文字列から厳密な型変換を行う場合（Integer("0x1a")）、バックトレースを取得してログ出力する場合（caller）、現在実行中のメソッド名を取得する場合（__method__）、引数を確実に特定の型に変換する場合（Array(), Hash()等）に使用される。

**主要な処理内容**：
1. Kernel#fail - raiseのエイリアス（例外を発生させる）
2. Kernel#caller - 実行スタックのバックトレースを取得
3. Kernel#__method__ - 現在のメソッド名をSymbolで返す
4. Kernel#__callee__ - 呼び出し時のメソッド名をSymbolで返す
5. Kernel#Integer - 引数を厳密にIntegerに変換
6. Kernel#Float - 引数を厳密にFloatに変換
7. Kernel#String - 引数をStringに変換
8. Kernel#Array - 引数をArrayに変換
9. Kernel#Hash - 引数をHashに変換

**関連システム・外部連携**：なし。mrubyコアのバックトレース機能および型変換機能に依存する。

**権限による制御**：全メソッドはプライベートメソッドとして登録され、レシーバを指定した呼び出しはできない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はライブラリ機能であり、画面との関連はない |

## 機能種別

ライブラリ拡張（型変換関数・デバッグ支援メソッドの追加）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| arg (Integer) | Object | Yes | 変換対象の値 | nilの場合TypeError |
| base (Integer) | Integer | No | 基数（0または2-36）、デフォルト0 | 文字列以外で指定するとArgumentError |
| arg (Float) | Object | Yes | 変換対象の値 | nilの場合TypeError |
| arg (String) | Object | Yes | 変換対象の値 | to_sで変換 |
| arg (Array) | Object | Yes | 変換対象の値 | to_aを試行、失敗時は[arg] |
| arg (Hash) | Object | Yes | 変換対象の値 | nil/[]は空Hash、それ以外はHash型チェック |
| start (caller) | Integer/Range | No | スキップするスタックフレーム数 | 負数はArgumentError |
| length (caller) | Integer | No | 取得するフレーム数 | 負数はArgumentError |

### 入力データソース

メソッド呼び出し時の引数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Integer()戻り値 | Integer | 変換されたInteger値 |
| Float()戻り値 | Float | 変換されたFloat値 |
| String()戻り値 | String | 変換されたString値 |
| Array()戻り値 | Array | 変換されたArray値 |
| Hash()戻り値 | Hash | 変換されたHash値 |
| caller戻り値 | Array/nil | バックトレース文字列の配列またはnil |
| __method__戻り値 | Symbol/nil | メソッド名のSymbolまたはnil |
| __callee__戻り値 | Symbol/nil | 呼び出し名のSymbolまたはnil |

### 出力先

メソッドの戻り値として呼び出し元に返却

## 処理フロー

### 処理シーケンス

```
1. Integer(arg, base=0)
   ├─ nilの場合: TypeError発生
   ├─ Float型: mrb_float_to_integerで切り捨て変換
   ├─ Integer型: そのまま返す
   ├─ String型: mrb_str_to_integerでパース
   └─ その他: mrb_ensure_integer_typeでTypeError

2. caller(start=1, length=nil)
   ├─ mrb_get_backtraceでバックトレース取得
   ├─ 引数なし: lev=1, n=bt_len-1
   ├─ Range引数: 範囲指定でスライス
   ├─ Integer引数: スキップ数指定
   └─ 2引数: スキップ数+取得数指定

3. __method__ / __callee__
   └─ コールスタック(ci)から直前のメソッドIDを取得
```

### フローチャート

```mermaid
flowchart TD
    A[Integer arg, base] --> B{arg == nil?}
    B -->|Yes| C[TypeError]
    B -->|No| D{arg型判定}
    D -->|Float| E[切り捨て変換]
    D -->|Integer| F[そのまま返す]
    D -->|String| G[文字列パース]
    D -->|その他| H{base != 0?}
    H -->|Yes| I[to_sして文字列パース]
    H -->|No| J[TypeError]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | Integer厳密変換 | String#to_iと異なり、不正な文字列はArgumentErrorを発生させる | Integer()での文字列変換時 |
| BR-42-02 | base指定制限 | base引数は文字列型の場合のみ有効、他の型ではArgumentError | Integer()でbase指定時 |
| BR-42-03 | callerデフォルト | 引数なしの場合、呼び出し元自身を除いた1段上からのバックトレースを返す | caller()呼び出し時 |
| BR-42-04 | プライベートメソッド | 全メソッドがプライベートとして登録される | 常時 |
| BR-42-05 | Hash空変換 | nil または空配列はHash()で空ハッシュに変換される | Hash(nil), Hash([]) |

### 計算ロジック

Integer()の基数変換: 文字列先頭のプレフィックス(0x, 0b, 0o, 0)を解釈してbase=0時に自動判定

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

該当なし（データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | TypeError | Integer(nil), Float(nil) | nilでない値を渡す |
| - | ArgumentError | Integer("abc")等の不正文字列 | 正しい数値文字列を渡す |
| - | ArgumentError | base指定で非文字列に適用 | 文字列のみにbase指定 |
| - | ArgumentError | caller(-1)等の負のレベル指定 | 0以上の値を渡す |
| - | TypeError | Hash([1,2,3])等の変換不可 | Hash型の値を渡す |

### リトライ仕様

リトライは不要

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

該当なし

## パフォーマンス要件

型変換メソッドはO(n)（n=文字列長）、callerはコールスタック深度に比例する。

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

callerメソッドはソースファイルパスと行番号を含むバックトレースを返すため、ファイルシステム情報の漏洩に注意が必要。

## 備考

- MRB_NO_FLOATマクロが定義されている場合、Kernel#Floatは利用不可
- failはmrb_f_raise（コア実装）を直接参照するエイリアス
- __method__はdefine_methodで定義されたメソッドの場合、環境(env)のmidを参照する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mrbgem.rake | `mrbgems/mruby-kernel-ext/mrbgem.rake` | gem定義。依存関係なし |

**読解のコツ**: `mrb_callinfo`構造体（コア定義）はコールスタックの各フレームを表す。`ci->mid`がメソッドID、`ci->proc`が実行中のProc。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kernel.c | `mrbgems/mruby-kernel-ext/src/kernel.c` | gem初期化とメソッド登録 |

**主要処理フロー**:
1. **305-311行目**: `mrb_mruby_kernel_ext_gem_init` - ROMテーブルによる一括メソッド登録
2. **291-303行目**: `kernel_ext_rom_entries` - 全メソッドのROMテーブル定義。全てMRB_MT_PRIVATEフラグ付き

#### Step 3: バックトレース取得(caller)を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kernel.c | `mrbgems/mruby-kernel-ext/src/kernel.c` | caller実装 |

**主要処理フロー**:
- **35-89行目**: `mrb_f_caller` - mrb_get_backtraceでバックトレース取得後、引数に応じてスライス
- **40行目**: 引数パース - `|oi`で省略可能なObjectとInteger
- **42行目**: `mrb_get_backtrace`でバックトレース配列取得
- **51-59行目**: Range引数のハンドリング
- **88行目**: `mrb_ary_new_from_values`でスライス結果を返す

#### Step 4: メソッド名取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | kernel.c | `mrbgems/mruby-kernel-ext/src/kernel.c` | __method__と__callee__の実装 |

**主要処理フロー**:
- **99-110行目**: `mrb_f_method` - ci(callinfo)を1つ遡り、procのenv->midまたはci->midを返す
- **120-129行目**: `mrb_f_callee` - ci->midのみ参照（エイリアス対応なし）

#### Step 5: 型変換関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | kernel.c | `mrbgems/mruby-kernel-ext/src/kernel.c` | Integer(), Float(), String(), Array(), Hash()の実装 |

**主要処理フロー**:
- **159-198行目**: `mrb_f_integer` - 型に応じた変換処理の分岐
- **213-222行目**: `mrb_f_float` - 文字列はmrb_str_to_dbl、他はmrb_ensure_float_type
- **236-242行目**: `mrb_f_string` - mrb_type_convertでto_s呼び出し
- **253-263行目**: `mrb_f_array` - to_aを試行、nilなら[arg]でラップ
- **279-289行目**: `mrb_f_hash` - nil/空配列は空Hash、他はHash型チェック

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

```
mrb_mruby_kernel_ext_gem_init
    |
    +-- MRB_MT_INIT_ROM(Kernel)
            +-- mrb_f_raise (fail) [コア関数参照]
            +-- mrb_f_caller
            |       +-- mrb_get_backtrace
            |       +-- mrb_range_beg_len
            |       +-- mrb_ary_new_from_values
            +-- mrb_f_method
            |       +-- ci->proc->e.env->mid 参照
            +-- mrb_f_callee
            |       +-- ci->mid 参照
            +-- mrb_f_integer
            |       +-- mrb_float_to_integer
            |       +-- mrb_str_to_integer
            |       +-- mrb_ensure_integer_type
            +-- mrb_f_float
            |       +-- mrb_str_to_dbl
            |       +-- mrb_ensure_float_type
            +-- mrb_f_string
            |       +-- mrb_type_convert (to_s)
            +-- mrb_f_array
            |       +-- mrb_type_convert_check (to_a)
            +-- mrb_f_hash
                    +-- mrb_ensure_hash_type
```

### データフロー図

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

"0x1a"            --> mrb_f_integer()              --> 26
123.999           --> mrb_f_integer()              --> 123
"123.456"         --> mrb_f_float()                --> 123.456
123456            --> mrb_f_string()               --> "123456"
1..5              --> mrb_f_array()                --> [1,2,3,4,5]
nil               --> mrb_f_hash()                 --> {}
(start,length)    --> mrb_f_caller()               --> ["file:line:in `method'", ...]
(なし)            --> mrb_f_method()               --> :method_name
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kernel.c | `mrbgems/mruby-kernel-ext/src/kernel.c` | ソース | 全メソッドのC実装 |
| mrbgem.rake | `mrbgems/mruby-kernel-ext/mrbgem.rake` | 設定 | gem定義ファイル |
| kernel.rb | `mrbgems/mruby-kernel-ext/test/kernel.rb` | テスト | 全メソッドのテスト |
