# 機能設計書 119-pop_backx

## 概要

本ドキュメントは、Hack Standard Library (HSL) の `C\pop_backx` 関数の機能設計について記述する。この関数は、Containerから最後の要素を削除して返す。空の場合は例外をスローする。

### 本機能の処理概要

`C\pop_backx` 関数は、Container（vec、dict、keyset、Vector等）から最後の要素を削除し、その要素を返す関数である。コレクションは `inout` パラメータとして渡され、関数呼び出し後に最後の要素が削除された状態になる。空のコレクションの場合は `InvariantException` をスローする。

**業務上の目的・背景**：スタックやキューなどのデータ構造の実装において、末尾要素の取り出し（ポップ操作）で空のコレクションをエラーとして扱いたい場合に使用される。空のコレクションが許容されない場面で、より安全なプログラミングを可能にする。

**機能の利用シーン**：
- スタック（LIFO）の実装でのpop操作（空は不正）
- 必ず要素が存在すべきバッファからの取り出し
- リストの末尾からの逐次処理（空になったらエラー）
- 事前に要素数が確認されている場面での安全なpop

**主要な処理内容**：
1. コレクションが空かどうかをチェック（invariant）
2. 空の場合は InvariantException をスロー
3. 空でない場合は `\array_pop` を呼び出して最後の要素を削除・返却
4. コレクションは inout により呼び出し元で変更される

**関連システム・外部連携**：本機能は外部システムとの連携はなく、PHP/Hack の組み込み関数 `\array_pop` に依存する。

**権限による制御**：特になし。ただし、`[write_props]` コンテキストを使用し、プロパティの書き込みが許可された環境でのみ実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 画面なし | - | 本機能はUIを持たないライブラリ関数 |

## 機能種別

データ操作 / 要素削除 / スタック操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $container | inout T (T as Container<Tv>) | Yes | 操作対象のコンテナ（inout参照） | 空でないこと（空の場合は例外） |

### 入力データソース

関数呼び出し時の引数として直接渡される。vec、dict、keyset、Vector等のContainerを実装する型を受け付ける。`inout` キーワードにより参照渡しとなる。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | Tv | 削除された最後の要素 |
| $container (inout) | T | 最後の要素が削除されたコンテナ |

### 出力先

関数の戻り値として呼び出し元に返却される。また、inout パラメータにより、元のコンテナが変更される。

## 処理フロー

### 処理シーケンス

```
1. 空チェック（invariant）
   └─ !is_empty($container) で判定
   └─ 空の場合は InvariantException をスロー
2. 空でない場合
   └─ \array_pop(inout $container) を呼び出し
   └─ 削除された要素を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{!is_empty?}
    B -->|Yes| C[array_pop呼び出し]
    C --> D[削除された要素を返却]
    B -->|No| E[InvariantException]
    D --> F[終了]
    E --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-119-01 | 空コレクション禁止 | 空のコレクションが渡された場合は例外をスロー | 常に適用 |
| BR-119-02 | 破壊的操作 | 元のコレクションから最後の要素が削除される | 常に適用 |
| BR-119-03 | null要素対応 | 最後の要素がnullの場合もnullを返す（例外ではない） | 要素自体がnullの場合 |
| BR-119-04 | イミュータブル非推奨 | イミュータブルなHack Collectionでは結果が未定義 | ImmVector等使用時 |

### 計算ロジック

特に計算ロジックは存在しない。コレクションの最後の要素を削除して返却する。

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvariantException | コレクションが空の場合 | 呼び出し前にコレクションが空でないことを確認するか、`pop_back` を使用 |

### リトライ仕様

リトライは不要。例外発生時は呼び出し元で適切にハンドリングする。

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

本機能はトランザクション管理を行わない。ただし、コレクションを破壊的に変更するため、操作前の状態が必要な場合は事前にコピーを取る必要がある。

## パフォーマンス要件

- 時間計算量: O(1) - インプレース操作の場合、O(N) - コピーが必要な場合
- 空間計算量: O(1) - インプレース操作の場合、O(N) - コピーが必要な場合
- vec の場合は通常 O(1)

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

本機能は純粋な関数であり、特別なセキュリティ考慮事項はない。入力データの検証は型システムにより保証される。

## 備考

- `pop_back` 関数（null を返す版）との使い分けが重要
- 空のコレクションがエラーケースである場合は本関数を使用
- 空のコレクションが正常ケースである場合は `pop_back` を使用
- イミュータブルな Hack Collection（ImmVector等）では未定義動作となる可能性がある
- `pop_frontx` は先頭要素を削除する版

---

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

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

### 推奨読解順序

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

Hack言語の `inout` パラメータとContainer型について理解することが重要。`inout` は参照渡しを意味し、関数内での変更が呼び出し元に反映される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | select.php | `src/c/select.php` | 関数シグネチャと inout パラメータの理解 |

**読解のコツ**: `T as Container<Tv>` は型パラメータ T が Container<Tv> を実装することを制約する。`inout T` は T 型の値を参照渡しで受け取ることを意味する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.php | `src/c/select.php` | pop_backx 関数の実装（402-411行目） |

**主要処理フロー**:
1. **402-404行目**: 関数シグネチャ - inout T (T as Container<Tv>) を受け取り Tv を返す
2. **405-408行目**: invariant で空チェック、空なら例外をスロー
3. **410行目**: array_pop を呼び出して最後の要素を削除・返却

#### Step 3: 関連関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.php | `src/c/select.php` | pop_back 関数（378-385行目）- null を返す版 |
| 3-2 | select.php | `src/c/select.php` | pop_frontx 関数（445-452行目）- 先頭要素を削除する版 |
| 3-3 | introspect.php | `src/c/introspect.php` | is_empty 関数（124-131行目）- 空チェック |

**主要処理フロー**:
- **378-385行目**: pop_back は空の場合 null を返す
- **402-411行目**: pop_backx は空の場合例外をスロー
- **445-452行目**: pop_frontx は先頭要素を削除（空で例外）

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

```
C\pop_backx(inout $container)
    │
    ├─ invariant(!C\is_empty($container), ...) [空チェック]
    │      │
    │      ├─ false → InvariantException
    │      │
    │      └─ true → \array_pop(inout $container) [要素削除]
    │                        │
    │                        └─ 削除された要素を返却
    │
    └─ $container が変更される（inout）
```

### データフロー図

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

Container<Tv> ───▶ invariant ───▶ array_pop ───▶ Tv（削除された要素）
   (inout)            │                │
                      │                └───▶ Container<Tv>（要素削除後）
                      │
                      └───▶ 空の場合 ───▶ InvariantException
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.php | `src/c/select.php` | ソース | pop_backx 関数の実装 |
| introspect.php | `src/c/introspect.php` | ソース | is_empty 関数の実装 |
| CSelectTest.php | `tests/c/CSelectTest.php` | テスト | pop_backx のユニットテスト（823-871行目） |
