252 lines
6.8 KiB
Markdown
252 lines
6.8 KiB
Markdown
# 🔥 Nyash finiシステム - 論理的解放フック
|
||
|
||
**最終更新: 2025年8月13日 - ChatGPT5協議による革命的設計完了**
|
||
|
||
## 🎯 概要
|
||
|
||
Nyashの`fini()`システムは、物理的メモリ破棄ではなく**論理的使用終了**を宣言する革新的なリソース管理システムです。Everything is Box哲学と完全に統合され、予測可能で安全なリソース管理を実現します。
|
||
|
||
## 🌟 核心コンセプト
|
||
|
||
### 📝 論理的解放フック
|
||
```nyash
|
||
box MyResource {
|
||
init { name, file }
|
||
|
||
fini() {
|
||
print("Resource " + me.name + " is being finalized")
|
||
// ファイルクローズなどのクリーンアップ処理
|
||
// 物理的メモリは共有参照が残っていても論理的には「終了」
|
||
}
|
||
}
|
||
```
|
||
|
||
**重要**: `fini()`は「このオブジェクトをもう使わない」という宣言であり、物理的な即時破棄ではありません。
|
||
|
||
## 🔄 実行順序(最終仕様)
|
||
|
||
### 自動カスケード解放
|
||
```nyash
|
||
box Pipeline {
|
||
init { r1, r2, r3, weak monitor }
|
||
|
||
fini() {
|
||
// 1) ユーザー定義処理(柔軟な順序制御可能)
|
||
me.r3.fini() // 依存関係でr3→r2の順
|
||
me.r2.fini()
|
||
|
||
// 2) 自動カスケード: 残りのr1がinit宣言順で自動解放
|
||
// 3) weakフィールドは対象外(lazy nil化)
|
||
}
|
||
}
|
||
```
|
||
|
||
### 決定的な解放順序
|
||
1. **finalized チェック** - 既に解放済みなら何もしない(idempotent)
|
||
2. **再入防止** - `in_finalization`フラグで再帰呼び出し防止
|
||
3. **ユーザー定義fini()実行** - カスタムクリーンアップ処理
|
||
4. **自動カスケード** - `init`宣言順で未処理フィールドを解放
|
||
5. **フィールドクリア** - 全フィールドを無効化
|
||
6. **finalized設定** - 以後の使用を禁止
|
||
|
||
## ⚠️ 厳格な禁止事項
|
||
|
||
### weak フィールドへのfini呼び出し禁止
|
||
```nyash
|
||
box Parent {
|
||
init { weak child }
|
||
|
||
fini() {
|
||
// ❌ 絶対にダメ!ビルドエラーまたは実行時エラー
|
||
// me.child.fini()
|
||
|
||
// ✅ 正しい方法
|
||
me.child = null // 参照解除
|
||
// または自動nil化に任せる
|
||
}
|
||
}
|
||
```
|
||
|
||
**理由**: weak参照は所有権を持たない非所有参照のため、fini()を呼ぶ権利がありません。
|
||
|
||
### finalized後の使用禁止
|
||
```nyash
|
||
box Example { }
|
||
|
||
local x = new Example()
|
||
x.fini()
|
||
|
||
// ❌ 以下は全てエラー
|
||
x.someMethod() // → "Instance was finalized; further use is prohibited"
|
||
x.field = value // → 同上
|
||
local val = x.field // → 同上
|
||
```
|
||
|
||
## 🏗️ 実装アーキテクチャ
|
||
|
||
### InstanceBox拡張
|
||
```rust
|
||
pub struct InstanceBox {
|
||
// 既存フィールド...
|
||
|
||
init_field_order: Vec<String>, // 決定的カスケード順序
|
||
weak_fields_union: HashSet<String>, // weak判定高速化
|
||
in_finalization: bool, // 再入防止
|
||
finalized: bool, // 使用禁止フラグ
|
||
}
|
||
```
|
||
|
||
### 実行時ガード
|
||
- **メソッド呼び出し**: `finalized`チェック → エラー
|
||
- **フィールドアクセス**: `finalized`チェック → エラー
|
||
- **フィールド代入**: `finalized`チェック → エラー
|
||
|
||
## 💡 使用例とパターン
|
||
|
||
### 基本的な使用例
|
||
```nyash
|
||
box FileHandler {
|
||
init { filename, handle }
|
||
|
||
pack(name) {
|
||
me.filename = name
|
||
me.handle = openFile(name)
|
||
}
|
||
|
||
fini() {
|
||
if (me.handle != null) {
|
||
closeFile(me.handle)
|
||
print("File " + me.filename + " closed")
|
||
}
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
local handler = new FileHandler("data.txt")
|
||
// ... ファイル操作 ...
|
||
handler.fini() // 明示的クリーンアップ
|
||
```
|
||
|
||
### 再代入時の自動解放
|
||
```nyash
|
||
box Holder { init { resource } }
|
||
box Resource { fini() { print("Resource cleaned up") } }
|
||
|
||
local h = new Holder()
|
||
h.resource = new Resource() // 新しいリソース設定
|
||
h.resource = new Resource() // → 前のリソースが自動的にfini()される
|
||
```
|
||
|
||
### カスタム解放順序
|
||
```nyash
|
||
box DatabaseConnection {
|
||
init { transaction, connection, logger }
|
||
|
||
fini() {
|
||
// 依存関係に基づく手動順序制御
|
||
if (me.transaction != null) {
|
||
me.transaction.rollback()
|
||
me.transaction.fini()
|
||
}
|
||
|
||
if (me.connection != null) {
|
||
me.connection.close()
|
||
me.connection.fini()
|
||
}
|
||
|
||
// loggerは自動カスケードに任せる
|
||
}
|
||
}
|
||
```
|
||
|
||
### 循環参照の安全な解決
|
||
```nyash
|
||
box Node {
|
||
init { data, weak parent, children }
|
||
|
||
pack(value) {
|
||
me.data = value
|
||
me.children = new ArrayBox()
|
||
}
|
||
|
||
addChild(child) {
|
||
me.children.push(child)
|
||
child.setParent(me) // 子→親はweak参照
|
||
}
|
||
|
||
fini() {
|
||
// 子ノードを先に解放
|
||
loop (me.children.length() > 0) {
|
||
local child = me.children.pop()
|
||
child.fini()
|
||
}
|
||
// 親への参照は自動的にnil化される
|
||
}
|
||
}
|
||
```
|
||
|
||
## 🧪 テストパターン
|
||
|
||
### 基本動作テスト
|
||
```nyash
|
||
box Counter {
|
||
init { value }
|
||
pack() { me.value = 0 }
|
||
increment() { me.value = me.value + 1 }
|
||
fini() { print("Counter finalized with value: " + me.value.toString()) }
|
||
}
|
||
|
||
local c = new Counter()
|
||
c.increment()
|
||
c.increment()
|
||
c.fini()
|
||
// c.increment() // → エラー: finalized後の使用禁止
|
||
```
|
||
|
||
### 循環参照テスト
|
||
```nyash
|
||
box Parent {
|
||
init { child }
|
||
pack() {
|
||
me.child = new Child()
|
||
me.child.setParent(me)
|
||
}
|
||
fini() { print("Parent finalized") }
|
||
}
|
||
|
||
box Child {
|
||
init { weak parent }
|
||
setParent(p) { me.parent = p }
|
||
fini() { print("Child finalized") }
|
||
}
|
||
|
||
local p = new Parent()
|
||
p.fini() // Parent → Child の順で解放、リークなし
|
||
```
|
||
|
||
## 🎯 期待される効果
|
||
|
||
### メモリ安全性
|
||
- **循環参照リーク完全防止**: weak参照とfiniの組み合わせ
|
||
- **二重解放防止**: idempotentな設計
|
||
- **使用禁止ガード**: finalized後の誤用防止
|
||
|
||
### 予測可能性
|
||
- **決定的順序**: init宣言順による自動カスケード
|
||
- **明示的制御**: ユーザー定義fini()での柔軟な順序指定
|
||
- **エラーメッセージ**: 明確で修正提案付きのエラー
|
||
|
||
### 開発体験
|
||
- **直感的**: リソースの「終了宣言」として理解しやすい
|
||
- **デバッグ容易**: 解放タイミングが明確
|
||
- **保守性**: 依存関係の変更に強い設計
|
||
|
||
## 📚 関連ドキュメント
|
||
|
||
- [weak参照設計](weak-reference-design.md) - 循環参照解決との統合
|
||
- [Everything is Box](design-philosophy.md) - 基本設計思想
|
||
- [言語リファレンス](language-reference.md) - 構文詳細
|
||
|
||
---
|
||
|
||
**Everything is Box, Everything is Finalized!** 🔥 |