# 機能設計書 27-出力機能

## 概要

本ドキュメントは、mrubyランタイムにおける出力機能の設計を記述する。Kernel#p, Kernel#print等の標準出力機能、バージョン情報・著作権情報の表示を提供する。

### 本機能の処理概要

mrubyの出力機能は、Rubyレベルのprint/p出力とC APIレベルの表示機能を提供する。Windows環境ではUTF-8からUTF-16への変換を行い、コンソールへの正しいUnicode出力をサポートする。

**業務上の目的・背景**：Rubyプログラムの基本的な出力手段として必須の機能である。また、mrubyコマンドのバージョン表示や著作権表示にも使用される。組み込み環境（MRB_NO_STDIO）では空実装となる。

**機能の利用シーン**：Rubyスクリプトでのprint/p出力、mrubyコマンド起動時のバージョン表示、エラーメッセージの出力、デバッグ時のオブジェクト検査。

**主要な処理内容**：
1. Kernel#print（mrb_print_m）: 引数を文字列化して標準出力に出力
2. mrb_p: オブジェクトをinspect形式で出力（改行付き）
3. mrb_show_version: MRUBY_DESCRIPTIONグローバル定数を表示
4. mrb_show_copyright: MRUBY_COPYRIGHTグローバル定数を表示
5. mrb_core_init_printabort: コア初期化失敗時のエラーメッセージ出力
6. Windows環境でのUTF-8→UTF-16変換コンソール出力

**関連システム・外部連携**：変数管理機能（定数取得）、Stringクラス（文字列変換）、Objectクラス（inspect）。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 標準出力への表示のみ |

## 機能種別

出力機能（標準出力への文字列出力）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| mrb | mrb_state* | Yes | mrubyインタプリタ状態 | - |
| obj | mrb_value | Yes（mrb_p用） | 出力対象オブジェクト | - |
| argv | mrb_value* | Yes（print用） | 出力対象の配列 | - |
| argc | mrb_int | Yes（print用） | 引数の数 | - |

### 入力データソース

- Rubyスクリプトからの引数
- C APIからの直接呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テキスト | 文字列 | 標準出力への文字列 |

### 出力先

標準出力（stdout）

## 処理フロー

### 処理シーケンス

```
1. mrb_print_m（Kernel#print）
   └─ 各引数をmrb_obj_as_string()で文字列化
      └─ printstr()で出力
         └─ printcstr()で実際のI/O
            ├─ Windows: WriteConsoleW（UTF-16変換）
            └─ その他: fwrite
2. mrb_p
   └─ nomem_err判定
      ├─ OOM時: 固定文字列"Out of memory\n"出力
      └─ 通常: mrb_inspect()→printstrln()
3. mrb_show_version
   └─ MRUBY_DESCRIPTION定数取得→printstrln()
```

### フローチャート

```mermaid
flowchart TD
    A[出力要求] --> B{関数種別}
    B -->|print| C[mrb_obj_as_string]
    B -->|p| D{OOM?}
    B -->|show_version| E[定数取得]
    C --> F[printstr]
    D -->|Yes| G[固定文字列出力]
    D -->|No| H[mrb_inspect]
    E --> F
    H --> F
    F --> I[printcstr]
    I --> J{Windows & isatty?}
    J -->|Yes| K[WriteConsoleW]
    J -->|No| L[fwrite]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | TTYフラッシュ | 端末出力時はfflush(stdout)を実行 | isatty(fileno(stdout))がtrue |
| BR-02 | OOM特別処理 | nomem_errオブジェクトの場合は固定文字列出力 | mrb_p |
| BR-03 | MRB_NO_STDIO | 定義時は全関数が空実装 | コンパイル時 |
| BR-04 | HAVE_MRUBY_IO_GEM | 定義時はmrb_print_mをスキップ（mruby-io gemが提供） | コンパイル時 |

### 計算ロジック

特になし。

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | OOM | nomem_err時のmrb_p | 固定文字列"Out of memory"出力 |

### リトライ仕様

リトライは不要。

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

特になし。

## パフォーマンス要件

- TTY出力時のみfflushを実行（非TTYへのパイプ出力時はバッファリング）

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

- 特になし

## 備考

- Windows環境ではMultiByteToWideChar/WriteConsoleWによるUTF-8→UTF-16変換を行う
- mruby-io gemが存在する場合、Kernel#printはそちらで提供される（HAVE_MRUBY_IO_GEM）

---

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

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

### 推奨読解順序

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

特別なデータ構造は使用しない。mrb_value（文字列型）が主な入出力データ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | print.c | `src/print.c` | mrb_print_m（69-81行目）: Kernel#printの実装 |
| 2-2 | print.c | `src/print.c` | mrb_p（84-95行目）: オブジェクトinspect出力 |
| 2-3 | print.c | `src/print.c` | mrb_show_version（98-102行目）: バージョン表示 |
| 2-4 | print.c | `src/print.c` | mrb_show_copyright（104-108行目）: 著作権表示 |

**主要処理フロー**:
1. **69-81行目**: mrb_get_args("*")で可変長引数取得→各引数をprintstr
2. **84-95行目**: nomem_errチェック→mrb_inspect→printstrln

#### Step 3: 内部出力関数

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | print.c | `src/print.c` | printcstr（26-43行目）: プラットフォーム別出力 |
| 3-2 | print.c | `src/print.c` | printstr（46-52行目）: mrb_value→文字列出力 |
| 3-3 | print.c | `src/print.c` | printstrln（54-59行目）: 改行付き出力 |

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

```
mrb_print_m (Kernel#print)
    │
    └─ printstr
           └─ printcstr
                  ├─ WriteConsoleW (Windows TTY)
                  └─ fwrite (その他)

mrb_p (C API)
    │
    ├─ printcstr ("Out of memory\n" - OOM時)
    └─ printstrln
           └─ printstr → printcstr

mrb_show_version
    │
    └─ mrb_const_get(MRUBY_DESCRIPTION)
           └─ printstrln → printstr → printcstr
```

### データフロー図

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

mrb_value (obj)     ───▶ mrb_obj_as_string()   ───▶ mrb_value (String)
                           │
mrb_value (String)  ───▶ printcstr()            ───▶ stdout (fwrite/WriteConsoleW)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| print.c | `src/print.c` | ソース | 出力機能の実装本体 |
| string.h | `include/mruby/string.h` | ヘッダ | RSTRING_PTR/LENマクロ |
| variable.h | `include/mruby/variable.h` | ヘッダ | mrb_const_get（定数取得） |
| version.c | `src/version.c` | ソース | バージョン定数定義 |
| kernel.c | `src/kernel.c` | ソース | Kernel#pメソッドの登録 |
