# 機能設計書 75-モジュールリフレクション

## 概要

本ドキュメントは、Julia言語におけるモジュールリフレクション機能の設計を記述する。`names`、`nameof`、`parentmodule`、`fullname`、`pathof`、`pkgdir`、`pkgversion` などの関数を通じて、モジュール情報の取得を提供する。

### 本機能の処理概要

モジュールリフレクション機能は、Juliaのモジュールシステムに関する情報をプログラム実行時に取得するための関数群を提供する。モジュールの名前、親モジュール、エクスポートされたシンボル、パッケージのファイルパス、バージョン情報などの取得を可能にする。

**業務上の目的・背景**：Juliaのモジュールシステムは名前空間管理とコード組織化の基盤であり、モジュール情報の実行時取得は、パッケージ管理、コード生成、テスト基盤、ドキュメント生成、IDEサポートなど多くのツールで必要とされる。特に `pathof` や `pkgdir` はパッケージのリソースファイルへのアクセスに不可欠である。

**機能の利用シーン**：パッケージのルートディレクトリ取得（データファイル等へのアクセス）、モジュールのエクスポートシンボル一覧取得（ドキュメント生成、自動補完）、モジュール階層の探索（依存関係解析）、パッケージバージョンの取得（互換性チェック）などで使用される。

**主要な処理内容**：
1. `names(m::Module; all, imported)` - モジュール内の名前（シンボル）一覧を取得
2. `nameof(m::Module)` - モジュールの名前をSymbolで取得
3. `nameof(f::Function)` - 関数の名前をSymbolで取得
4. `parentmodule(m::Module)` - 親モジュールを取得
5. `parentmodule(f::Function)` - 関数が定義されたモジュールを取得
6. `parentmodule(f, types)` - 特定のメソッドが定義されたモジュールを取得
7. `fullname(m::Module)` - Mainからのフルパス名をタプルで取得
8. `pathof(m::Module)` - モジュールのソースファイルパスを取得
9. `pkgdir(m::Module)` - パッケージのルートディレクトリを取得
10. `pkgversion(m::Module)` - パッケージのバージョンを取得

**関連システム・外部連携**：パッケージローディングシステム（base/loading.jl）と連携。Project.tomlの解析によるバージョン情報の取得を含む。

**権限による制御**：特別な権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Juliaプロンプト（julia>） | 補助機能 | プロンプトにアクティブモジュール名を表示。using/importによるモジュール操作をREPLから実行 |

## 機能種別

モジュール情報取得・内省処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| m | Module | Yes | 対象モジュール | 有効なモジュール |
| all | Bool | No | 非公開シンボルも含める（デフォルト: false） | true/false |
| imported | Bool | No | インポートしたシンボルも含める（デフォルト: false） | true/false |

### 入力データソース

- Juliaプログラムからの直接呼び出し
- パッケージ管理システムからの間接呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| symbol_names | Vector{Symbol} | names()の結果 |
| module_name | Symbol | nameof()の結果 |
| parent | Module | parentmodule()の結果 |
| full_name | Tuple{Symbol...} | fullname()の結果 |
| source_path | Union{String,Nothing} | pathof()の結果 |
| package_dir | Union{String,Nothing} | pkgdir()の結果 |
| version | Union{VersionNumber,Nothing} | pkgversion()の結果 |

### 出力先

戻り値としてJuliaプログラムに返却

## 処理フロー

### 処理シーケンス

```
1. モジュール情報要求
   └─ names / nameof / parentmodule / pathof 等の呼び出し
2. モジュールメタデータアクセス
   └─ Module構造体のフィールドまたはCcall経由で情報取得
3. [pathof/pkgdir] パッケージパス解決
   └─ Base.loaded_modulesからパス情報を取得
4. [pkgversion] Project.toml解析
   └─ pkgdirからProject.tomlを読み込みバージョンを抽出
5. 結果の整形・返却
```

### フローチャート

```mermaid
flowchart TD
    A[モジュールリフレクション要求] --> B{関数の種類}
    B -->|names| C[ccall jl_module_names]
    B -->|nameof| D[Module.nameフィールド]
    B -->|parentmodule| E[Module.parentフィールド]
    B -->|pathof| F[loaded_modules検索]
    B -->|pkgdir| G[pathof → dirname]
    B -->|pkgversion| H[pkgdir → Project.toml解析]
    C --> I[Vector{Symbol}]
    D --> J[Symbol]
    E --> K[Module]
    F --> L[String/Nothing]
    G --> M[String/Nothing]
    H --> N[VersionNumber/Nothing]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-01 | names フィルタ | all=falseの場合、publicシンボルのみ返す | names呼び出し |
| BR-75-02 | pathof制約 | プリコンパイルされていないモジュールはpathofがnothingを返す場合がある | pathof呼び出し |
| BR-75-03 | pkgdir解決 | pathofの結果からsrcディレクトリを除去してパッケージルートを返す | pkgdir呼び出し |
| BR-75-04 | fullname再帰 | fullnameはMainに到達するまで再帰的に親モジュールを辿る | fullname呼び出し |
| BR-75-05 | pkgversion解析 | Project.tomlのversionフィールドをVersionNumberとして解析 | pkgversion呼び出し |

### 計算ロジック

`fullname(m)` は `parentmodule(m)` を再帰的に呼び出し、Main に到達するまでのモジュール名をタプルとして構築する。例: `fullname(Base.Iterators)` は `(:Base, :Iterators)` を返す。

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

### 操作別データベース影響一覧

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ErrorException | 例外 | 未定義シンボルに対するwhich(m, s) | 正しいシンボルを指定 |
| - | Nothing返却 | プリコンパイルされていないモジュールのpathof | nothingチェック |
| - | Nothing返却 | バージョン情報のないパッケージのpkgversion | nothingチェック |

### リトライ仕様

リトライ不要

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

該当なし

## パフォーマンス要件

- nameof、parentmoduleはModule構造体のフィールドアクセスであり極めて高速
- names()はモジュールのバインディングテーブル走査を伴う
- pkgversion()はファイルI/O（Project.toml読み込み）を伴うため比較的遅い

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

特になし。モジュール情報は全て公開情報である。

## 備考

- `names(m; all=true)` は内部シンボル（#で始まるgensym等）も含む
- `binding_module(m, s)` で実際のバインディング元モジュールを特定可能
- Julia 1.1以降で `pkgversion` が利用可能

---

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

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

### 推奨読解順序

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

Module型の基本構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | boot.jl | `base/boot.jl` | Module型はCore組み込み型。name, parentフィールドを持つ |

**読解のコツ**: Module型はJuliaランタイムのC実装（src/module.c）に対応する。Juliaレベルでは不透明型のように扱われ、ccallでランタイム関数を呼び出して情報を取得する。

#### Step 2: 名前・モジュール取得関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | reflection.jl | `base/reflection.jl` | nameof(f::Function)（1018-1020行目）: typeof(f).name.singletonname でジェネリック関数名を取得 |
| 2-2 | reflection.jl | `base/reflection.jl` | parentmodule(f::Function)（1033行目）: parentmodule(typeof(f))に委譲 |
| 2-3 | reflection.jl | `base/reflection.jl` | parentmodule(f, types)（1041-1047行目）: methods(f, types)の最初のメソッドのモジュールを返す |

**主要処理フロー**:
1. **1018-1020行目**: `nameof(f::Function)` - typeof(f).name.singletonname
2. **1022-1025行目**: `nameof(f::Core.IntrinsicFunction)` - jl_intrinsic_name ccall
3. **1041-1047行目**: `parentmodule(f, types)` - methods → first → parentmodule

#### Step 3: パッケージパス・バージョン関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | loading.jl | `base/loading.jl` | pathof, pkgdir, pkgversion の実装。loaded_modules辞書を参照 |

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

```
nameof(f::Function)
    └─ typeof(f).name.singletonname

parentmodule(f::Function)
    └─ parentmodule(typeof(f))

parentmodule(f, types)
    │
    ├─ methods(f, types)
    └─ parentmodule(first(m))
           └─ m.module

pathof(m::Module)
    └─ Base._path_of_loaded_module(m)  // loaded_modules検索

pkgdir(m::Module)
    │
    ├─ pathof(m)
    └─ dirname(dirname(path))  // src/Foo.jl → Foo/

pkgversion(m::Module)
    │
    ├─ pkgdir(m)
    └─ TOML.parsefile(joinpath(dir, "Project.toml"))
           └─ VersionNumber(d["version"])
```

### データフロー図

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

Function f ──────▶ nameof()           ──────▶ Symbol
                    typeof(f).name.singletonname

Module m ────────▶ names(m; all)      ──────▶ Vector{Symbol}
                    ccall jl_module_names

Module m ────────▶ pathof(m)          ──────▶ String / Nothing
                    loaded_modules検索

Module m ────────▶ pkgversion(m)      ──────▶ VersionNumber / Nothing
                    pkgdir → Project.toml
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| reflection.jl | `base/reflection.jl` | ソース | nameof, parentmodule等の関数定義 |
| loading.jl | `base/loading.jl` | ソース | pathof, pkgdir, pkgversionの実装 |
| module.jl | `base/module.jl` | ソース | Moduleに関する基本操作 |
| boot.jl | `base/boot.jl` | ソース | Module型の基盤定義 |
| module.c | `src/module.c` | ソース（C） | モジュールシステムのCランタイム実装 |
