# 機能設計書 118-pop_back

## 概要

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

### 本機能の処理概要

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

**業務上の目的・背景**：スタックやキューなどのデータ構造の実装において、末尾要素の取り出し（ポップ操作）は基本的な操作である。コレクションを破壊的に変更しながら要素を取り出す必要がある場面で使用される。

**機能の利用シーン**：
- スタック（LIFO）の実装でのpop操作
- バッファからの末尾要素の取り出し
- リストの末尾からの逐次処理
- ワークキューの末尾からのタスク取得

**主要な処理内容**：
1. コレクションが空かどうかをチェック
2. 空の場合は null を返却
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 | 削除された最後の要素、または空の場合はnull |
| $container (inout) | T | 最後の要素が削除されたコンテナ |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 空チェック
   └─ is_empty($container) で判定
2. 空の場合
   └─ null を返却
3. 空でない場合
   └─ \array_pop(inout $container) を呼び出し
   └─ 削除された要素を返却
```

### フローチャート

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

## ビジネスルール

### 業務ルール

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

### 計算ロジック

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数はエラーをスローしない | - |

### リトライ仕様

エラーが発生しないため、リトライ仕様は不要。

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

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

## パフォーマンス要件

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

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

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

## 備考

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

---

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

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

### 推奨読解順序

#### 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_back 関数の実装（378-385行目） |

**主要処理フロー**:
1. **378-380行目**: 関数シグネチャ - inout T (T as Container<Tv>) を受け取り ?Tv を返す
2. **381-383行目**: is_empty で空チェック、空なら null を返却
3. **384行目**: array_pop を呼び出して最後の要素を削除・返却

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.php | `src/c/select.php` | pop_backx 関数（402-411行目）- 例外をスローする版 |
| 3-2 | select.php | `src/c/select.php` | pop_front 関数（435-440行目）- 先頭要素を削除する版 |
| 3-3 | introspect.php | `src/c/introspect.php` | is_empty 関数（124-131行目）- 空チェック |

**主要処理フロー**:
- **378-385行目**: pop_back は空の場合 null を返す
- **402-411行目**: pop_backx は空の場合例外をスロー
- **435-440行目**: pop_front は先頭要素を削除

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

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

### データフロー図

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

Container<Tv> ───▶ 空チェック ───▶ array_pop ───▶ ?Tv（削除された要素）
   (inout)              │                │
                        │                └───▶ Container<Tv>（要素削除後）
                        │
                        └───▶ 空の場合 ───▶ null
```

### 関連ファイル一覧

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