# 機能設計書 5-関数定義（def）

## 概要

本ドキュメントは、Nushellにおけるカスタム関数（コマンド）定義機能について定義する。`def`コマンドを使用することで、ユーザーは独自のコマンドを定義し、再利用可能なロジックをカプセル化できる。

### 本機能の処理概要

**業務上の目的・背景**：コードの再利用性と保守性を高めるため、繰り返し使用する処理をカスタムコマンドとして定義する必要がある。Nushellの`def`は、型付きパラメータ、フラグ、デフォルト値、rest引数など豊富な機能を提供し、堅牢なスクリプト開発を支援する。

**機能の利用シーン**：
- よく使う処理のカプセル化
- パラメータ化された再利用可能なスクリプト作成
- 外部コマンドのラッパー定義
- 環境変数を操作するユーティリティ関数

**主要な処理内容**：
1. `def name [params] { body }` - 基本的な関数定義
2. `def --env` - 環境変数変更を呼び出し元に伝播
3. `def --wrapped` - 外部コマンドラッパー用（未知のフラグを許可）
4. 型シグネチャ - 入力/出力型の指定
5. パラメータ定義 - 位置引数、オプション引数、フラグ、rest引数

**関連システム・外部連携**：nu-parser（構文解析）、nu-engine（評価）と連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 主画面 | 関数定義の入力と実行 |

## 機能種別

関数定義 / コマンド登録

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| def_name | String | Yes | 定義するコマンド名 | 有効な識別子 |
| params | Signature | Yes | パラメータリスト（[]内） | 有効なシグネチャ |
| block | Closure | Yes | 関数本体（{}内） | 有効なクロージャ |
| --env | Switch | No | 環境変数変更を伝播 | - |
| --wrapped | Switch | No | 未知フラグを許可 | rest引数が必要 |

### 入力データソース

- ユーザーからのコマンドライン入力
- スクリプトファイル
- モジュールファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PipelineData | PipelineData | Empty（定義自体は値を返さない） |

### 出力先

- EngineState（コマンド宣言として登録）

## 処理フロー

### 処理シーケンス

```
1. パース時
   └─ コマンド名の検証
   └─ シグネチャの解析
   └─ ブロックの解析
   └─ DeclIdの割り当て
   └─ EngineStateへの登録
2. 呼び出し時
   └─ 引数のバインディング
   └─ キャプチャ変数の収集
   └─ ブロックの評価
   └─ 環境のリダイレクト（--env時）
```

### フローチャート

```mermaid
flowchart TD
    A[def コマンド] --> B[パース時処理]
    B --> C[コマンド名検証]
    C --> D[シグネチャ解析]
    D --> E[ブロック解析]
    E --> F[DeclId割り当て]
    F --> G[EngineState登録]
    G --> H[定義完了]
    I[関数呼び出し] --> J[eval_call]
    J --> K[引数バインディング]
    K --> L[キャプチャ変数収集]
    L --> M[ブロック評価]
    M --> N{--env?}
    N -->|Yes| O[環境リダイレクト]
    N -->|No| P[結果返却]
    O --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 環境伝播 | --envで環境変更が呼び出し元に伝播 | def --env |
| BR-002 | ラップモード | --wrappedで未知フラグを許可 | def --wrapped |
| BR-003 | 型シグネチャ | `: type -> type`で入出力型を指定 | シグネチャ後 |
| BR-004 | 再帰制限 | 関数呼び出しの再帰は50回まで | 関数呼び出し時 |
| BR-005 | スコープ | 定義されたスコープ内でのみ有効 | モジュール/オーバーレイ |

### 計算ロジック

特になし。

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

本機能はデータベース操作を直接行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| RecursionLimitReached | 実行エラー | 再帰が50回を超過 | 再帰ロジックを見直す |
| CantConvert | 型エラー | 引数の型が不一致 | 型を確認 |
| MissingPositional | 引数エラー | 必須引数がない | 引数を追加 |

### リトライ仕様

リトライは行わない。

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

関数定義はトランザクション管理を行わない。

## パフォーマンス要件

特になし。

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

- --envは明示的に指定が必要（デフォルトは環境非伝播）

## 備考

- defはパーサーキーワードとして実装
- export defでモジュールからエクスポート可能

---

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

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

### 推奨読解順序

#### Step 1: コマンド定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | def.rs | `crates/nu-cmd-lang/src/core_commands/def.rs` | defコマンドの実装 |
| 1-2 | export_def.rs | `crates/nu-cmd-lang/src/core_commands/export_def.rs` | export defの実装 |

**主要処理フロー（def.rs）**:
- **16-25行目**: シグネチャ定義。def_name, params, block, --env, --wrapped
- **36-44行目**: run関数（PipelineData::empty()を返すのみ）
- **46-79行目**: examples（環境伝播、ラップモード、型シグネチャ）

#### Step 2: パース処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parse_keywords.rs | `crates/nu-parser/src/parse_keywords.rs` | parse_def関数 |

#### Step 3: 実行処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | eval.rs | `crates/nu-engine/src/eval.rs` | eval_call（27-159行目） |

**主要処理フロー**:
- **27-45行目**: block_idがある場合（ユーザー定義関数）の処理
- **30行目**: gather_capturesでキャプチャ変数を収集
- **36-45行目**: 再帰制限チェック
- **47-106行目**: 引数のバインディング
- **155-157行目**: redirect_envで環境リダイレクト

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

```
def name [params] { body }
    │
    ├─ パース時
    │      └─ parse_def (parse_keywords.rs)
    │             ├─ シグネチャ解析
    │             ├─ ブロック解析
    │             └─ DeclId登録
    │
    └─ 呼び出し時
           └─ eval_call (eval.rs)
                  ├─ gather_captures
                  ├─ 引数バインディング
                  ├─ eval_block_with_early_return
                  └─ redirect_env (--env時)
```

### データフロー図

```
[定義]                  [登録]                       [呼び出し]

def foo [x] { ... }
    │
    ▼
パース ───────────▶ DeclId登録 ───────────▶ EngineState
                                                │
                                                ▼
foo 123 ──────────▶ eval_call ──────────▶ 引数バインド
                       │
                       ▼
                   ブロック評価 ───────────▶ 結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| def.rs | `crates/nu-cmd-lang/src/core_commands/def.rs` | ソース | defコマンド |
| export_def.rs | `crates/nu-cmd-lang/src/core_commands/export_def.rs` | ソース | export defコマンド |
| parse_keywords.rs | `crates/nu-parser/src/parse_keywords.rs` | ソース | defのパース処理 |
| eval.rs | `crates/nu-engine/src/eval.rs` | ソース | eval_call（関数呼び出し） |
| signature.rs | `crates/nu-protocol/src/signature.rs` | ソース | シグネチャ定義 |
