Files
hakorune/src/instance.rs
Moe Charm ca8939b05f 🔥 feat: BoxBase+BoxCore革命完全達成!全Box型統一アーキテクチャ完成
🎉 歴史的達成: 30+Box型の完全統一アーキテクチャ移行完了
 爆速一括処理完了Box型
- RegexBox: 正規表現処理 🔍
- IntentBox: 通信世界管理 📡
- P2PBox: P2P通信システム 🌐
- InstanceBox: インスタンス管理 📦
- ChannelBox/MessageBox: チャンネル通信 📬
- ErrorBox: エラー処理 ⚠️
- MethodBox: メソッド管理 🔧
- TypeBox: 型情報管理 📋
- NyashFutureBox: 非同期処理 
- HttpClientBox: HTTP通信 🌍
- NyashStreamBox: ストリーム処理 🔄

🎯 BoxBase+BoxCore革命の完全達成
- unsafe ID生成完全撲滅 → AtomicU64安全化
- 統一インターフェース確立 → CharmFlow互換性問題根本解決
- 一貫したfmt_box()表示システム
- スレッドセーフ性とメモリ安全性完全保証

🚀 技術革命の成果
- コード重複大幅削減
- 保守性・拡張性の飛躍的向上
- 将来のBox型追加時の互換性完全保証
- Everything is Box哲学の技術的完成

📊 戦略的成功
- ゆっくり丁寧 → パターン確立
- 爆速一括処理 → 効率完成
- 高品質と効率性の完璧な両立

次段階: ビルトインBox継承システム実装準備完了!

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-11 12:09:14 +09:00

229 lines
7.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* Nyash Instance System - Box Instance Implementation
*
* BoxインスタンスとClassBoxの実装
* Everything is Box哲学に基づくオブジェクト指向システム
*/
use crate::box_trait::{NyashBox, StringBox, BoolBox, VoidBox, BoxCore, BoxBase};
use crate::ast::ASTNode;
use std::collections::HashMap;
use std::fmt::{Debug, Display};
use std::any::Any;
use std::sync::{Arc, Mutex};
/// Boxインスタンス - フィールドとメソッドを持つオブジェクト
#[derive(Debug, Clone)]
pub struct InstanceBox {
/// クラス名
pub class_name: String,
/// フィールド値
pub fields: Arc<Mutex<HashMap<String, Box<dyn NyashBox>>>>,
/// メソッド定義ClassBoxから共有
pub methods: Arc<HashMap<String, ASTNode>>,
/// Box基底
base: BoxBase,
/// 解放済みフラグ
finalized: Arc<Mutex<bool>>,
}
impl InstanceBox {
pub fn new(class_name: String, fields: Vec<String>, methods: HashMap<String, ASTNode>) -> Self {
// フィールドをVoidBoxで初期化
let mut field_map = HashMap::new();
for field in fields {
field_map.insert(field, Box::new(VoidBox::new()) as Box<dyn NyashBox>);
}
Self {
class_name,
fields: Arc::new(Mutex::new(field_map)),
methods: Arc::new(methods),
base: BoxBase::new(),
finalized: Arc::new(Mutex::new(false)),
}
}
/// フィールドの値を取得
pub fn get_field(&self, field_name: &str) -> Option<Box<dyn NyashBox>> {
self.fields.lock().unwrap().get(field_name).map(|v| v.clone_box())
}
/// フィールドに値を設定
pub fn set_field(&self, field_name: &str, value: Box<dyn NyashBox>) -> Result<(), String> {
let mut fields = self.fields.lock().unwrap();
if fields.contains_key(field_name) {
fields.insert(field_name.to_string(), value);
Ok(())
} else {
Err(format!("Field '{}' does not exist in {}", field_name, self.class_name))
}
}
/// 🌍 GlobalBox用フィールドを動的に追加・設定
pub fn set_field_dynamic(&mut self, field_name: String, value: Box<dyn NyashBox>) {
let mut fields = self.fields.lock().unwrap();
fields.insert(field_name, value);
}
/// メソッド定義を取得
pub fn get_method(&self, method_name: &str) -> Option<&ASTNode> {
self.methods.get(method_name)
}
/// メソッドが存在するかチェック
pub fn has_method(&self, method_name: &str) -> bool {
self.methods.contains_key(method_name)
}
/// 🌍 GlobalBox用メソッドを動的に追加 - 🔥 暗黙オーバーライド禁止による安全実装
pub fn add_method(&mut self, method_name: String, method_ast: ASTNode) -> Result<(), String> {
// Arc<T>は不変なので、新しいHashMapを作成してArcで包む
let mut new_methods = (*self.methods).clone();
// 🚨 暗黙オーバーライド禁止:既存メソッドの検査
if let Some(existing_method) = new_methods.get(&method_name) {
// 新しいメソッドのoverride状態を確認
let is_override = match &method_ast {
crate::ast::ASTNode::FunctionDeclaration { is_override, .. } => *is_override,
_ => false, // FunctionDeclaration以外はオーバーライドなし
};
if !is_override {
// 🔥 明示的オーバーライド革命overrideキーワードなしの重複を禁止
return Err(format!(
"🚨 EXPLICIT OVERRIDE REQUIRED: Method '{}' already exists.\n\
💡 To replace the existing method, use 'override {}(...) {{ ... }}'.\n\
🌟 This is Nyash's explicit delegation philosophy - no hidden overrides!",
method_name, method_name
));
}
// override宣言があれば、明示的な置換として許可
eprintln!("🔥 EXPLICIT OVERRIDE: Method '{}' replaced with override declaration", method_name);
}
new_methods.insert(method_name, method_ast);
self.methods = Arc::new(new_methods);
Ok(())
}
/// fini()メソッド - インスタンスの解放
pub fn fini(&self) -> Result<(), String> {
let mut finalized = self.finalized.lock().unwrap();
if *finalized {
// 既に解放済みなら何もしない
return Ok(());
}
*finalized = true;
// フィールドをクリア
let mut fields = self.fields.lock().unwrap();
fields.clear();
Ok(())
}
/// 解放済みかチェック
pub fn is_finalized(&self) -> bool {
*self.finalized.lock().unwrap()
}
}
impl NyashBox for InstanceBox {
fn to_string_box(&self) -> StringBox {
StringBox::new(format!("<{} instance #{}>", self.class_name, self.base.id()))
}
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_instance) = other.as_any().downcast_ref::<InstanceBox>() {
// 同じインスタンスIDなら等しい
BoolBox::new(self.base.id() == other_instance.base.id())
} else {
BoolBox::new(false)
}
}
fn type_name(&self) -> &'static str {
"InstanceBox"
}
fn clone_box(&self) -> Box<dyn NyashBox> {
// インスタンスは同じフィールドを共有
Box::new(self.clone())
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl BoxCore for InstanceBox {
fn box_id(&self) -> u64 {
self.base.id()
}
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "<{} instance #{}>", self.class_name, self.base.id())
}
}
impl Display for InstanceBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.fmt_box(f)
}
}
// ===== Tests =====
#[cfg(test)]
mod tests {
use super::*;
use crate::box_trait::IntegerBox;
#[test]
fn test_instance_creation() {
let fields = vec!["x".to_string(), "y".to_string()];
let methods = HashMap::new();
let instance = InstanceBox::new("Point".to_string(), fields, methods);
assert_eq!(instance.class_name, "Point");
assert!(instance.get_field("x").is_some());
assert!(instance.get_field("y").is_some());
assert!(instance.get_field("z").is_none());
}
#[test]
fn test_field_access() {
let fields = vec!["value".to_string()];
let methods = HashMap::new();
let instance = InstanceBox::new("TestBox".to_string(), fields, methods);
// フィールドに値を設定
let int_value = Box::new(IntegerBox::new(42)) as Box<dyn NyashBox>;
instance.set_field("value", int_value).unwrap();
// フィールドの値を取得
let retrieved = instance.get_field("value").unwrap();
let int_box = retrieved.as_any().downcast_ref::<IntegerBox>().unwrap();
assert_eq!(int_box.value, 42);
}
#[test]
fn test_instance_equality() {
let instance1 = InstanceBox::new("Test".to_string(), vec![], HashMap::new());
let instance2 = InstanceBox::new("Test".to_string(), vec![], HashMap::new());
// 異なるインスタンスは等しくない
assert!(!instance1.equals(&instance2).value);
// 同じインスタンスは等しい
assert!(instance1.equals(&instance1).value);
}
}