feat(plugin): Fix plugin BoxRef return and Box argument support
- Fixed deadlock in FileBox plugin copyFrom implementation (single lock) - Added TLV Handle (tag=8) parsing in calls.rs for returned BoxRefs - Improved plugin loader with config path consistency and detailed logging - Fixed loader routing for proper Handle type_id/fini_method_id resolution - Added detailed logging for TLV encoding/decoding in plugin_loader_v2 Test docs/examples/plugin_boxref_return.nyash now works correctly: - cloneSelf() returns FileBox Handle properly - copyFrom(Box) accepts plugin Box arguments - Both FileBox instances close and fini correctly 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
547
docs/guides/tutorials/1_getting_started.md
Normal file
547
docs/guides/tutorials/1_getting_started.md
Normal file
@ -0,0 +1,547 @@
|
||||
# 🚀 Getting Started with Nyash - Practical Guide
|
||||
|
||||
**最終更新: 2025年8月8日**
|
||||
|
||||
## 🎯 5分でNyashを理解する
|
||||
|
||||
Nyashは「Everything is Box」哲学に基づく、シンプルで強力なプログラミング言語です。
|
||||
このガイドでは、実際にコードを書きながらNyashの機能を学んでいきます。
|
||||
|
||||
## ⚡ クイックスタート
|
||||
|
||||
### **1. 環境構築**
|
||||
```bash
|
||||
# リポジトリのクローン
|
||||
git clone [repository-url]
|
||||
cd nyash/nyash-rust
|
||||
|
||||
# ビルド
|
||||
cargo build
|
||||
|
||||
# 実行
|
||||
./target/debug/nyash your_program.nyash
|
||||
```
|
||||
|
||||
### **2. はじめてのNyashプログラム**
|
||||
`hello.nyash`を作成:
|
||||
```nyash
|
||||
print("Hello, Nyash World!")
|
||||
print("Everything is Box! 🎉")
|
||||
```
|
||||
|
||||
実行:
|
||||
```bash
|
||||
./target/debug/nyash hello.nyash
|
||||
```
|
||||
|
||||
出力:
|
||||
```
|
||||
Hello, Nyash World!
|
||||
Everything is Box! 🎉
|
||||
```
|
||||
|
||||
## 📚 基本構文チュートリアル
|
||||
|
||||
### **Step 1: 変数と初期化**
|
||||
```nyash
|
||||
# 🎯 新機能:初期化付き変数宣言
|
||||
local name = "Alice"
|
||||
local age = 25
|
||||
local height = 165.5
|
||||
local isStudent = true
|
||||
|
||||
print("Name: " + name)
|
||||
print("Age: " + age)
|
||||
print("Height: " + height)
|
||||
print("Student: " + isStudent)
|
||||
|
||||
# 複数変数の同時宣言・初期化
|
||||
local x = 10, y = 20, z = 30
|
||||
print("Sum: " + (x + y + z)) # 60
|
||||
|
||||
# 混合宣言(初期化あり・なし)
|
||||
local initialized = 42, uninitialized, another = "test"
|
||||
uninitialized = "assigned later"
|
||||
print("Values: " + initialized + ", " + uninitialized + ", " + another)
|
||||
```
|
||||
|
||||
### **Step 2: 演算子の使用**
|
||||
```nyash
|
||||
local a = 10
|
||||
local b = 3
|
||||
|
||||
# 算術演算子
|
||||
print("Addition: " + (a + b)) # 13
|
||||
print("Subtraction: " + (a - b)) # 7
|
||||
print("Multiplication: " + (a * b)) # 30
|
||||
print("Division: " + (a / b)) # 3.3333333333333335
|
||||
|
||||
# 論理演算子(自然言語ライク)
|
||||
local hasPermission = true
|
||||
local isLoggedIn = true
|
||||
local canAccess = hasPermission and isLoggedIn
|
||||
print("Can access: " + canAccess) # true
|
||||
|
||||
local isDenied = not canAccess
|
||||
print("Is denied: " + isDenied) # false
|
||||
|
||||
# 比較演算子
|
||||
print("a > b: " + (a > b)) # true
|
||||
print("a == b: " + (a == b)) # false
|
||||
```
|
||||
|
||||
### **Step 3: 制御構造**
|
||||
```nyash
|
||||
function testControlFlow() {
|
||||
local score = 85
|
||||
|
||||
# if文
|
||||
if score >= 90 {
|
||||
print("Grade: A")
|
||||
} else if score >= 80 {
|
||||
print("Grade: B") # これが実行される
|
||||
} else {
|
||||
print("Grade: C or below")
|
||||
}
|
||||
|
||||
# ループ(統一構文)
|
||||
local count = 0
|
||||
loop(count < 3) {
|
||||
print("Count: " + count)
|
||||
count = count + 1
|
||||
if count == 2 {
|
||||
print("Breaking at 2")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testControlFlow()
|
||||
```
|
||||
|
||||
### **Step 4: Box(クラス)の定義**
|
||||
```nyash
|
||||
box Person {
|
||||
init { name, age, email } # フィールド定義(カンマ必須!)
|
||||
|
||||
# コンストラクタ(引数サポート)
|
||||
Person(n, a, e) {
|
||||
me.name = n
|
||||
me.age = a
|
||||
me.email = e
|
||||
print("Person created: " + me.name)
|
||||
}
|
||||
|
||||
# メソッド
|
||||
introduce() {
|
||||
print("Hi, I'm " + me.name + ", age " + me.age)
|
||||
}
|
||||
|
||||
getInfo() {
|
||||
return me.name + " (" + me.age + ") - " + me.email
|
||||
}
|
||||
|
||||
# デストラクタ
|
||||
fini() {
|
||||
print("Person destroyed: " + me.name)
|
||||
}
|
||||
}
|
||||
|
||||
# 使用例
|
||||
person = new Person("Bob", 30, "bob@example.com")
|
||||
person.introduce()
|
||||
print("Info: " + person.getInfo())
|
||||
```
|
||||
|
||||
## 🏭 実践例:Calculator アプリ
|
||||
|
||||
完全なCalculatorアプリを実装:
|
||||
|
||||
```nyash
|
||||
# 📱 Calculator App - Nyash版
|
||||
|
||||
box Calculator {
|
||||
init { history }
|
||||
|
||||
Calculator() {
|
||||
me.history = new ArrayBox()
|
||||
print("🧮 Calculator initialized!")
|
||||
}
|
||||
|
||||
add(a, b) {
|
||||
local result = a + b
|
||||
me.addToHistory("ADD", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
subtract(a, b) {
|
||||
local result = a - b
|
||||
me.addToHistory("SUB", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
multiply(a, b) {
|
||||
local result = a * b
|
||||
me.addToHistory("MUL", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
divide(a, b) {
|
||||
if b == 0 {
|
||||
print("❌ Error: Division by zero!")
|
||||
return 0
|
||||
}
|
||||
local result = a / b
|
||||
me.addToHistory("DIV", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
addToHistory(op, a, b, result) {
|
||||
local record = op + ": " + a + " " + op + " " + b + " = " + result
|
||||
me.history.push(record)
|
||||
}
|
||||
|
||||
showHistory() {
|
||||
print("📊 Calculation History:")
|
||||
local size = me.history.size()
|
||||
local i = 0
|
||||
loop(i < size) {
|
||||
print(" " + (i + 1) + ". " + me.history.get(i))
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
me.history = new ArrayBox()
|
||||
print("🧹 History cleared!")
|
||||
}
|
||||
}
|
||||
|
||||
# ✨ Calculator使用例
|
||||
calc = new Calculator()
|
||||
|
||||
print("=== Basic Operations ===")
|
||||
print("10 + 5 = " + calc.add(10, 5))
|
||||
print("10 - 3 = " + calc.subtract(10, 3))
|
||||
print("4 * 7 = " + calc.multiply(4, 7))
|
||||
print("15 / 3 = " + calc.divide(15, 3))
|
||||
print("10 / 0 = " + calc.divide(10, 0)) # ゼロ除算エラーテスト
|
||||
|
||||
print("")
|
||||
calc.showHistory()
|
||||
|
||||
print("")
|
||||
print("=== Complex Calculations ===")
|
||||
local complex1 = calc.add(calc.multiply(3, 4), calc.divide(20, 4))
|
||||
print("(3 * 4) + (20 / 4) = " + complex1)
|
||||
|
||||
calc.showHistory()
|
||||
```
|
||||
|
||||
## ⚡ 並行処理の実践
|
||||
|
||||
```nyash
|
||||
# 🚀 Parallel Processing Example
|
||||
|
||||
function heavyComputation(iterations) {
|
||||
print("⚙️ Starting computation with " + iterations + " iterations...")
|
||||
|
||||
local sum = 0
|
||||
local i = 0
|
||||
loop(i < iterations) {
|
||||
sum = sum + (i * i)
|
||||
i = i + 1
|
||||
|
||||
# 進捗表示(1000回毎)
|
||||
if (i % 1000) == 0 {
|
||||
print(" Progress: " + i + "/" + iterations)
|
||||
}
|
||||
}
|
||||
|
||||
print("✅ Computation completed: " + sum)
|
||||
return sum
|
||||
}
|
||||
|
||||
function parallelDemo() {
|
||||
print("🚀 Starting parallel computations...")
|
||||
|
||||
# 3つのタスクを並行実行
|
||||
future1 = nowait heavyComputation(5000)
|
||||
future2 = nowait heavyComputation(3000)
|
||||
future3 = nowait heavyComputation(4000)
|
||||
|
||||
print("⏳ All tasks started. Waiting for results...")
|
||||
|
||||
# 結果を待機して取得
|
||||
result1 = await future1
|
||||
result2 = await future2
|
||||
result3 = await future3
|
||||
|
||||
local total = result1 + result2 + result3
|
||||
print("🎉 All tasks completed!")
|
||||
print("Total sum: " + total)
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
# 実行
|
||||
parallelDemo()
|
||||
```
|
||||
|
||||
## 🏗️ Static Box(名前空間)の活用
|
||||
|
||||
```nyash
|
||||
# 🏗️ Utility Classes with Static Boxes
|
||||
|
||||
static box MathUtils {
|
||||
init { PI, E }
|
||||
|
||||
static {
|
||||
me.PI = 3.14159265359
|
||||
me.E = 2.71828182846
|
||||
}
|
||||
|
||||
square(x) {
|
||||
return x * x
|
||||
}
|
||||
|
||||
circleArea(radius) {
|
||||
return me.PI * me.square(radius)
|
||||
}
|
||||
|
||||
power(base, exp) {
|
||||
local result = 1
|
||||
local i = 0
|
||||
loop(i < exp) {
|
||||
result = result * base
|
||||
i = i + 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
static box StringUtils {
|
||||
init { EMPTY }
|
||||
|
||||
static {
|
||||
me.EMPTY = ""
|
||||
}
|
||||
|
||||
reverse(str) {
|
||||
# 簡易的な実装例
|
||||
return "REVERSED:" + str
|
||||
}
|
||||
|
||||
isEmpty(str) {
|
||||
return str == me.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
# 使用例
|
||||
print("π = " + MathUtils.PI)
|
||||
print("Circle area (r=5): " + MathUtils.circleArea(5))
|
||||
print("2^8 = " + MathUtils.power(2, 8))
|
||||
|
||||
print("Empty check: " + StringUtils.isEmpty(""))
|
||||
print("Reverse: " + StringUtils.reverse("Hello"))
|
||||
```
|
||||
|
||||
## 🐛 デバッグ機能の活用
|
||||
|
||||
```nyash
|
||||
# 🐛 Debug Features Showcase
|
||||
|
||||
box DebugExample {
|
||||
init { data, counter }
|
||||
|
||||
DebugExample() {
|
||||
me.data = "example"
|
||||
me.counter = 0
|
||||
}
|
||||
|
||||
process() {
|
||||
me.counter = me.counter + 1
|
||||
return "Processed #" + me.counter
|
||||
}
|
||||
}
|
||||
|
||||
function debuggingDemo() {
|
||||
# DebugBoxでトラッキング開始
|
||||
DEBUG = new DebugBox()
|
||||
DEBUG.startTracking()
|
||||
|
||||
print("🔍 Creating objects for debugging...")
|
||||
|
||||
# オブジェクトを作成してトラッキング
|
||||
obj1 = new DebugExample()
|
||||
obj2 = new DebugExample()
|
||||
|
||||
DEBUG.trackBox(obj1, "Primary Object")
|
||||
DEBUG.trackBox(obj2, "Secondary Object")
|
||||
|
||||
# 処理実行
|
||||
result1 = obj1.process()
|
||||
result2 = obj2.process()
|
||||
result3 = obj1.process()
|
||||
|
||||
print("Results: " + result1 + ", " + result2 + ", " + result3)
|
||||
|
||||
# デバッグレポート表示
|
||||
print("")
|
||||
print("=== Memory Report ===")
|
||||
print(DEBUG.memoryReport())
|
||||
|
||||
print("")
|
||||
print("=== Full Debug Dump ===")
|
||||
print(DEBUG.dumpAll())
|
||||
|
||||
# デバッグ情報をファイルに保存
|
||||
DEBUG.saveToFile("debug_output.txt")
|
||||
print("🎉 Debug information saved to debug_output.txt")
|
||||
}
|
||||
|
||||
debuggingDemo()
|
||||
```
|
||||
|
||||
## 📦 ファイル組織とモジュール
|
||||
|
||||
### **プロジェクト構造**
|
||||
```
|
||||
my_nyash_project/
|
||||
├── main.nyash # メインプログラム
|
||||
├── utils/
|
||||
│ ├── math.nyash # 数学ユーティリティ
|
||||
│ ├── string.nyash # 文字列ユーティリティ
|
||||
│ └── debug.nyash # デバッグ関数
|
||||
└── models/
|
||||
├── person.nyash # Personクラス
|
||||
└── calculator.nyash # Calculatorクラス
|
||||
```
|
||||
|
||||
### **main.nyash**
|
||||
```nyash
|
||||
# 📦 Module System Example
|
||||
|
||||
include "utils/math.nyash"
|
||||
include "utils/string.nyash"
|
||||
include "models/person.nyash"
|
||||
include "models/calculator.nyash"
|
||||
|
||||
function main() {
|
||||
print("🚀 Multi-module Nyash Application")
|
||||
|
||||
# 各モジュールの機能を使用
|
||||
person = new Person("Alice", 25, "alice@example.com")
|
||||
person.introduce()
|
||||
|
||||
calc = new Calculator()
|
||||
result = calc.add(10, 20)
|
||||
print("Calculation result: " + result)
|
||||
}
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
## 🎯 ベストプラクティス
|
||||
|
||||
### **1. 変数命名**
|
||||
```nyash
|
||||
# ✅ Good
|
||||
local userName = "alice"
|
||||
local totalAmount = 1000
|
||||
local isComplete = true
|
||||
|
||||
# ❌ Avoid
|
||||
local x = "alice"
|
||||
local amt = 1000
|
||||
local flag = true
|
||||
```
|
||||
|
||||
### **2. Box設計**
|
||||
```nyash
|
||||
# ✅ Good: 明確な責任分離
|
||||
box UserAccount {
|
||||
init { username, email, balance }
|
||||
|
||||
UserAccount(u, e) {
|
||||
me.username = u
|
||||
me.email = e
|
||||
me.balance = 0
|
||||
}
|
||||
|
||||
deposit(amount) {
|
||||
me.balance = me.balance + amount
|
||||
}
|
||||
}
|
||||
|
||||
# ❌ Avoid: 責任の混在
|
||||
box EverythingBox {
|
||||
# 多すぎる責任を持たせない
|
||||
}
|
||||
```
|
||||
|
||||
### **3. エラーハンドリング**
|
||||
```nyash
|
||||
function safeOperation(a, b) {
|
||||
if b == 0 {
|
||||
print("❌ Error: Division by zero")
|
||||
return 0
|
||||
}
|
||||
return a / b
|
||||
}
|
||||
```
|
||||
|
||||
### **4. パフォーマンス考慮**
|
||||
```nyash
|
||||
# ✅ 効率的:static box使用
|
||||
result = MathUtils.calculate(data)
|
||||
|
||||
# ✅ 効率的:初期化付き宣言
|
||||
local result = heavyCalculation(), cache = new MapBox()
|
||||
|
||||
# ⚠️ 注意:不要なオブジェクト生成を避ける
|
||||
loop(i < 1000) {
|
||||
# 毎回new しない設計を心がける
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 次のステップ
|
||||
|
||||
### **学習順序**
|
||||
1. ✅ **基本構文** - このガイドで完了
|
||||
2. **並行処理** - `test_async_*.nyash`を参考に
|
||||
3. **Static Box応用** - ユーティリティクラス作成
|
||||
4. **デバッグ技法** - DebugBox完全活用
|
||||
5. **アプリケーション開発** - 実践的なプロジェクト
|
||||
|
||||
### **サンプルプログラム**
|
||||
```bash
|
||||
# 実装済みサンプル
|
||||
./target/debug/nyash test_local_init.nyash # 初期化付き変数
|
||||
./target/debug/nyash app_dice_rpg.nyash # RPGバトルゲーム
|
||||
./target/debug/nyash app_statistics.nyash # 統計計算
|
||||
./target/debug/nyash test_async_parallel.nyash # 並行処理
|
||||
```
|
||||
|
||||
### **リファレンス**
|
||||
- `docs/LANGUAGE_OVERVIEW_2025.md` - 言語全体概要
|
||||
- `docs/TECHNICAL_ARCHITECTURE_2025.md` - 技術仕様
|
||||
- `CLAUDE.md` - 開発者向け詳細情報
|
||||
|
||||
## 🎉 おめでとうございます!
|
||||
|
||||
このガイドでNyashの主要機能を学習しました!
|
||||
|
||||
**習得内容:**
|
||||
- ✅ 基本構文(変数・演算子・制御構造)
|
||||
- ✅ Box(クラス)定義とオブジェクト指向
|
||||
- ✅ 並行処理・非同期プログラミング
|
||||
- ✅ Static Box・名前空間システム
|
||||
- ✅ デバッグ機能・開発支援ツール
|
||||
- ✅ 実践的なアプリケーション開発
|
||||
|
||||
**Nyashでプログラミングの新しい可能性を探究してください!** 🚀
|
||||
|
||||
---
|
||||
*Getting Started Guide v1.0*
|
||||
*Everything is Box - Start Simple, Think Big*
|
||||
254
docs/guides/tutorials/2_language_guide.md
Normal file
254
docs/guides/tutorials/2_language_guide.md
Normal file
@ -0,0 +1,254 @@
|
||||
# 📚 Nyash Programming Language - 完全ガイド
|
||||
|
||||
**最終更新: 2025年8月12日 - Phase 1完了, P2P実装準備完了**
|
||||
|
||||
## 📖 概要
|
||||
|
||||
Nyashは「Everything is Box」哲学に基づく革新的なプログラミング言語です。
|
||||
Rust製インタープリターによる高性能実行と、直感的な構文により、学習しやすく実用的な言語として完成しました。
|
||||
|
||||
## 🎯 核心哲学: "Everything is Box"
|
||||
|
||||
```nyash
|
||||
# すべてのデータがBoxとして統一的に表現される
|
||||
number = 42 # IntegerBox
|
||||
text = "hello" # StringBox
|
||||
flag = true # BoolBox
|
||||
array = new ArrayBox() # ArrayBox
|
||||
debug = new DebugBox() # DebugBox
|
||||
```
|
||||
|
||||
**重要な利点:**
|
||||
- **統一性**: すべてのデータが共通インターフェース
|
||||
- **メモリ安全性**: Arc<Mutex>パターンで完全スレッドセーフ
|
||||
- **拡張性**: 新しいBox型を容易に追加可能
|
||||
|
||||
---
|
||||
|
||||
## 🔤 言語構文リファレンス
|
||||
|
||||
### 🏷️ **変数宣言・スコープ**
|
||||
|
||||
```nyash
|
||||
// ローカル変数宣言
|
||||
local x, y
|
||||
local name = "Alice"
|
||||
|
||||
// 所有権移転変数(関数戻り値用)
|
||||
outbox result = compute()
|
||||
|
||||
// グローバル変数
|
||||
global CONFIG = "dev"
|
||||
```
|
||||
|
||||
### 🧮 **演算子**
|
||||
|
||||
```nyash
|
||||
// 算術演算子
|
||||
a + b, a - b, a * b, a / b
|
||||
|
||||
// 比較演算子
|
||||
a == b, a != b, a < b, a > b, a <= b, a >= b
|
||||
|
||||
// 論理演算子
|
||||
not condition, a and b, a or b
|
||||
|
||||
// Cross-type演算 (Phase 1で完全実装)
|
||||
10 + 3.14 // → 13.14 (型変換)
|
||||
"Value: " + 42 // → "Value: 42" (文字列連結)
|
||||
```
|
||||
|
||||
### 🏗️ **Box定義・デリゲーション**
|
||||
|
||||
#### 基本Box定義
|
||||
```nyash
|
||||
box User {
|
||||
init { name, email } // フィールド宣言
|
||||
|
||||
pack(userName, userEmail) { // 🎁 Box哲学の具現化!
|
||||
me.name = userName
|
||||
me.email = userEmail
|
||||
}
|
||||
|
||||
greet() {
|
||||
print("Hello, " + me.name)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### デリゲーション (2025-08 革命)
|
||||
```nyash
|
||||
box AdminUser from User { // 🔥 from構文でデリゲーション
|
||||
init { permissions }
|
||||
|
||||
pack(adminName, adminEmail, perms) {
|
||||
from User.pack(adminName, adminEmail) // 親のpack呼び出し
|
||||
me.permissions = perms
|
||||
}
|
||||
|
||||
override greet() { // 明示的オーバーライド
|
||||
from User.greet() // 親メソッド呼び出し
|
||||
print("Admin privileges: " + me.permissions)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Static Box Main パターン
|
||||
```nyash
|
||||
static box Main {
|
||||
init { console, result }
|
||||
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
me.console.log("🎉 Everything is Box!")
|
||||
return "Success!"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 🔄 **制御構造**
|
||||
|
||||
```nyash
|
||||
// 条件分岐
|
||||
if condition {
|
||||
// 処理
|
||||
} else {
|
||||
// 別処理
|
||||
}
|
||||
|
||||
// ループ(唯一の正しい形式)
|
||||
loop(condition) {
|
||||
// 処理
|
||||
if breakCondition {
|
||||
break
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 ビルトインBox型
|
||||
|
||||
### 基本型
|
||||
- **StringBox**: 文字列 (`"hello"`)
|
||||
- **IntegerBox**: 整数 (`42`)
|
||||
- **FloatBox**: 浮動小数点数 (`new FloatBox(3.14)`) ✅ Phase 1完了
|
||||
- **BoolBox**: 真偽値 (`true`, `false`)
|
||||
- **NullBox**: NULL値 (`null`)
|
||||
|
||||
### データ構造
|
||||
- **ArrayBox**: 配列 (`new ArrayBox()`) ✅ Phase 1で sort/reverse/indexOf/slice 実装
|
||||
- **MapBox**: 連想配列 (`new MapBox()`)
|
||||
|
||||
### ユーティリティ
|
||||
- **ConsoleBox**: コンソール出力 (`new ConsoleBox()`)
|
||||
- **DebugBox**: デバッグ機能 (`new DebugBox()`)
|
||||
- **MathBox**: 数学関数 (`new MathBox()`)
|
||||
- **TimeBox**: 時刻処理 (`new TimeBox()`)
|
||||
- **DateTimeBox**: 日時処理 (`new DateTimeBox()`) ✅ Phase 1で完全動作
|
||||
|
||||
### 高度機能
|
||||
- **RandomBox**: 乱数生成
|
||||
- **BufferBox**: バッファ操作
|
||||
- **RegexBox**: 正規表現
|
||||
- **JSONBox**: JSON処理
|
||||
- **StreamBox**: ストリーム処理
|
||||
|
||||
### P2P通信 (Phase 2実装中)
|
||||
- **IntentBox**: 構造化メッセージ (実装予定)
|
||||
- **P2PBox**: P2P通信ノード (実装予定)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 実用例
|
||||
|
||||
### データ処理例
|
||||
```nyash
|
||||
// 配列操作
|
||||
local numbers = new ArrayBox()
|
||||
numbers.push(3)
|
||||
numbers.push(1)
|
||||
numbers.push(2)
|
||||
numbers.sort() // [1, 2, 3]
|
||||
|
||||
// 型変換・演算
|
||||
local result = 10 + new FloatBox(3.14) // 13.14
|
||||
print("Result: " + result.toString())
|
||||
```
|
||||
|
||||
### P2P通信例 (将来実装)
|
||||
```nyash
|
||||
// P2Pノード作成
|
||||
local node_a = new P2PBox("alice", transport: "inprocess")
|
||||
local node_b = new P2PBox("bob", transport: "inprocess")
|
||||
|
||||
// メッセージ受信ハンドラ
|
||||
node_b.on("chat.message", function(intent, from) {
|
||||
print("From " + from + ": " + intent.payload.text)
|
||||
})
|
||||
|
||||
// 構造化メッセージ送信
|
||||
local msg = new IntentBox("chat.message", { text: "Hello P2P!" })
|
||||
node_a.send("bob", msg) // → "From alice: Hello P2P!"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要な注意点
|
||||
|
||||
### 必須のコンマ
|
||||
```nyash
|
||||
// ✅ 正しい
|
||||
init { field1, field2 }
|
||||
|
||||
// ❌ 間違い(CPU暴走の原因)
|
||||
init { field1 field2 }
|
||||
```
|
||||
|
||||
### 変数宣言厳密化
|
||||
```nyash
|
||||
// ✅ 明示宣言必須
|
||||
local x
|
||||
x = 42
|
||||
|
||||
// ❌ 未宣言変数への代入はエラー
|
||||
y = 42 // Runtime Error + 修正提案
|
||||
```
|
||||
|
||||
### ループ構文統一
|
||||
```nyash
|
||||
// ✅ 唯一の正しい形式
|
||||
loop(condition) { }
|
||||
|
||||
// ❌ 削除済み構文
|
||||
while condition { } // 使用不可
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 実装状況 (2025-08-12)
|
||||
|
||||
### ✅ Phase 1完了
|
||||
- FloatBox toString() メソッド
|
||||
- ArrayBox 改良 (sort/reverse/indexOf/slice)
|
||||
- Cross-type演算子システム
|
||||
- 包括的テストスイート (188行)
|
||||
|
||||
### 🚧 Phase 2実装中
|
||||
- IntentBox (構造化メッセージ)
|
||||
- MessageBus (プロセス内シングルトン)
|
||||
- P2PBox (P2P通信ノード)
|
||||
|
||||
### 📋 将来予定
|
||||
- WebSocket/WebRTC通信
|
||||
- 非同期処理 (async/await)
|
||||
- 追加のBox型拡張
|
||||
|
||||
---
|
||||
|
||||
**🎉 Nyashで「Everything is Box」の世界を体験しよう!**
|
||||
|
||||
📚 **関連ドキュメント:**
|
||||
- [Getting Started](GETTING_STARTED.md) - 環境構築・最初の一歩
|
||||
- [P2P Guide](P2P_GUIDE.md) - P2P通信システム完全ガイド
|
||||
- [Built-in Boxes](reference/builtin-boxes.md) - ビルトインBox詳細リファレンス
|
||||
102
docs/guides/tutorials/playground_guide.md
Normal file
102
docs/guides/tutorials/playground_guide.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Nyash Playground Guide(ブラウザデモ活用ガイド)
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
## リンク
|
||||
- Playground: https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html
|
||||
|
||||
## ねらい
|
||||
- 言語の要点(init/fini/weak/スコープ解放)を“動く例”で体感
|
||||
- レビュワーやチームへの共有・再現を容易化(ゼロインストール)
|
||||
|
||||
## 使い方(最短)
|
||||
1) 上記リンクを開く
|
||||
2) 下のサンプルコードをコピー&ペースト
|
||||
3) Run/実行ボタンで結果確認(ログ・出力・エラー挙動)
|
||||
|
||||
---
|
||||
|
||||
## シナリオ1: 循環参照 vs weak(自動nil化)
|
||||
|
||||
```nyash
|
||||
# Parent↔Child の双方向参照。
|
||||
# 子→親は weak 参照にして、リークとダングリングを防ぐ。
|
||||
|
||||
box Parent {
|
||||
init { child }
|
||||
pack() {
|
||||
me.child = new Child()
|
||||
me.child.setParent(me)
|
||||
}
|
||||
getName() { return "P" }
|
||||
fini() { print("Parent.fini") }
|
||||
}
|
||||
|
||||
box Child {
|
||||
init { weak parent }
|
||||
setParent(p) { me.parent = p }
|
||||
show() {
|
||||
if (me.parent != null) { print("parent=" + me.parent.getName()) }
|
||||
else { print("parent is gone") }
|
||||
}
|
||||
fini() { print("Child.fini") }
|
||||
}
|
||||
|
||||
p = new Parent()
|
||||
p.child.show() # => parent=P
|
||||
|
||||
# 親を明示的に破棄(fini 呼出しが発火する環境であればここで解放)
|
||||
p.fini()
|
||||
|
||||
# 親が破棄済みなので、weak 参照は自動的に nil 化される
|
||||
p.child.show() # => parent is gone(想定)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- `init { weak parent }`で弱参照を宣言
|
||||
- 参照先が破棄されるとアクセス時に自動で`null`扱い
|
||||
|
||||
---
|
||||
|
||||
## シナリオ2: 再代入時の fini 発火(予備解放)
|
||||
|
||||
```nyash
|
||||
box Holder { init { obj } }
|
||||
box Thing { fini() { print("Thing.fini") } }
|
||||
|
||||
h = new Holder()
|
||||
h.obj = new Thing()
|
||||
h.obj = new Thing() # 旧 obj に対して fini() が呼ばれる(ログで確認)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- フィールド再代入の節目で `fini()` が自動呼出し
|
||||
- 二重解放は内部で抑止(安全側)
|
||||
|
||||
---
|
||||
|
||||
## シナリオ3: スコープ抜けでローカル解放
|
||||
|
||||
```nyash
|
||||
function make() {
|
||||
local t
|
||||
t = new Thing()
|
||||
# 関数を抜けるとスコープ追跡により t が解放される
|
||||
}
|
||||
|
||||
box Thing { fini() { print("Thing.fini (scope)") } }
|
||||
|
||||
make() # => Thing.fini (scope)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- `local`で宣言された変数はスコープ終了時に一括解放
|
||||
- 暗黙ではなく構文規約で明示(未宣言代入はエラー)
|
||||
|
||||
---
|
||||
|
||||
## Tips(レビュー/論文向け)
|
||||
- 論文やREADMEから本ガイドへリンクし、コピー&ペーストで再現
|
||||
- 期待ログ(例: `Thing.fini`)を明記して、挙動の確認を容易に
|
||||
- 比較のため「weakなし版」と「weakあり版」を並記
|
||||
|
||||
Reference in New Issue
Block a user