# Nyash Macro Examples - 世界最強マクロ言語への具体例 **更新日**: 2025-09-18 **ステータス**: 設計完了、実装待ち ## 🎯 マクロ分類と優先度 | 優先度 | マクロ | 実用性 | 実装コスト | 特徴 | |--------|--------|--------|------------|------| | 🥇 **MVP** | @derive | ⭐⭐⭐⭐ | ⭐⭐ | ボイラープレート除去 | | 🥈 **早期** | @validate | ⭐⭐⭐⭐ | ⭐⭐⭐ | 型安全・入力品質 | | 🥈 **早期** | @config_schema | ⭐⭐⭐⭐ | ⭐⭐ | 実アプリ即効 | | 🥉 **段階** | @api_client | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | プロダクション | | 🥉 **段階** | @sql_schema | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 企業利用 | | 🏅 **実験** | @html_dsl | ⭐⭐⭐ | ⭐⭐⭐ | 表現力・デモ | ## 🔥 1. @derive系マクロ(MVP最優先) ### 基本例 ```nyash @derive(Equals, ToString, Clone, Json) box UserBox { name: StringBox age: IntegerBox email: StringBox } ``` ### 自動生成されるメソッド ```nyash // @derive(Equals) → equals method method equals(other: UserBox) -> BoolBox { return me.name == other.name && me.age == other.age && me.email == other.email } // @derive(ToString) → toString method method toString() -> StringBox { return "UserBox(name=" + me.name + ", age=" + me.age + ", email=" + me.email + ")" } // @derive(Clone) → clone method method clone() -> UserBox { return new UserBox(me.name, me.age, me.email) } // @derive(Json) → toJson/fromJson methods method toJson() -> JsonBox { return JsonBox.object([ ["name", me.name], ["age", me.age], ["email", me.email] ]) } ``` ### Property System統合 ```nyash @derive(Equals, ToString) box AdvancedBox { // stored fields name: StringBox // computed fields も自動でderiveに含まれる! display_name: StringBox { me.name.toUpperCase() } // once fields も含まれる once uuid: StringBox { generateUUID() } } // 生成されるequalsはcomputed/onceも含む method equals(other: AdvancedBox) -> BoolBox { return me.name == other.name && me.display_name == other.display_name && me.uuid == other.uuid // onceプロパティも比較 } ``` ## 🛡️ 2. @validate系マクロ(型安全革命) ### 基本バリデーション ```nyash @validate box UserBox { @required @email email: StringBox @range(0, 150) @required age: IntegerBox @min_length(8) @optional password: StringBox @pattern("^[a-zA-Z]+$") @required name: StringBox } ``` ### 自動生成されるバリデーション ```nyash // setter methods with validation method set_email(value: StringBox) { if value.length() == 0 { throw new ValidationError("email is required") } if !value.contains("@") { throw new ValidationError("invalid email format") } me.email = value } method set_age(value: IntegerBox) { if value < 0 || value > 150 { throw new ValidationError("age must be between 0 and 150") } me.age = value } method set_name(value: StringBox) { if value.length() == 0 { throw new ValidationError("name is required") } if !value.matches("^[a-zA-Z]+$") { throw new ValidationError("name must contain only letters") } me.name = value } // bulk validation method method validate() -> Result { try { me.validate_email() me.validate_age() me.validate_name() return Ok(true) } catch(ValidationError e) { return Err(e) } } ``` ### Property System統合 ```nyash @validate box ConfigBox { @required @env("DATABASE_URL") database_url: StringBox // computed property でもバリデーション適用 @range(1, 100) max_connections: IntegerBox { me.calculate_connections() } // validation はcomputed propertyの計算時に実行 } ``` ## ⚙️ 3. @config_schema系マクロ(実アプリ即効) ### 環境変数ベース設定 ```nyash @config_schema box AppConfigBox { @env("DATABASE_URL") @required database_url: StringBox @env("REDIS_URL") @default("redis://localhost:6379") redis_url: StringBox @env("DEBUG") @default(false) @parse_bool debug_mode: BoolBox @env("MAX_CONNECTIONS") @default(100) @range(1, 1000) @parse_int max_connections: IntegerBox @env("LOG_LEVEL") @default("INFO") @enum(["DEBUG", "INFO", "WARN", "ERROR"]) log_level: StringBox } ``` ### 自動生成される設定ローダー ```nyash // 静的ローダーメソッド static method load() -> Result { local config = new AppConfigBox() // required環境変数チェック local database_url = EnvBox.get("DATABASE_URL") if database_url.is_none() { return Err(new ConfigError("DATABASE_URL is required")) } config.database_url = database_url.unwrap() // デフォルト値付き設定 config.redis_url = EnvBox.get_or("REDIS_URL", "redis://localhost:6379") config.debug_mode = EnvBox.get_or("DEBUG", "false").parse_bool() config.max_connections = EnvBox.get_or("MAX_CONNECTIONS", "100").parse_int() // バリデーション実行 if config.max_connections < 1 || config.max_connections > 1000 { return Err(new ConfigError("MAX_CONNECTIONS must be between 1 and 1000")) } return Ok(config) } // 設定リロードメソッド method reload() -> Result { local new_config = AppConfigBox.load() if new_config.is_err() { return Err(new_config.unwrap_err()) } // 現在の設定を更新 local config = new_config.unwrap() me.database_url = config.database_url me.redis_url = config.redis_url // ... other fields return Ok(true) } ``` ### Property System統合 ```nyash @config_schema box LiveConfigBox { @env("API_HOST") @required api_host: StringBox @env("API_PORT") @default(8080) @parse_int api_port: IntegerBox // computed: 設定から自動でURL生成 api_url: StringBox { "http://" + me.api_host + ":" + me.api_port } // once: 重い初期化処理 once connection_pool: PoolBox { createPool(me.api_url, me.max_connections) } } ``` ## 🌐 4. @api_client系マクロ(プロダクション級) ### OpenAPI仕様ベース生成 ```nyash @api_client("https://petstore.swagger.io/v2/swagger.json") box PetStoreApiBox { base_url: StringBox = "https://petstore.swagger.io/v2" api_key: StringBox // 以下のメソッドが自動生成される: // getPetById(id: IntegerBox) -> Promise // addPet(pet: PetBox) -> Promise // updatePet(pet: PetBox) -> Promise // deletePet(id: IntegerBox) -> Promise // findPetsByStatus(status: StringBox) -> Promise> } ``` ### 自動生成されるAPIメソッド ```nyash // GET /pet/{petId} method getPetById(id: IntegerBox) -> Promise { local url = me.base_url + "/pet/" + id.toString() local request = HttpRequestBox.new() .url(url) .method("GET") .header("api_key", me.api_key) return HttpClientBox.send(request) .then(|response| { if response.status() != 200 { throw new ApiError("Failed to get pet: " + response.status()) } return PetBox.fromJson(response.body()) }) } // POST /pet method addPet(pet: PetBox) -> Promise { local url = me.base_url + "/pet" local request = HttpRequestBox.new() .url(url) .method("POST") .header("Content-Type", "application/json") .header("api_key", me.api_key) .body(pet.toJson().toString()) return HttpClientBox.send(request) .then(|response| { if response.status() != 200 { throw new ApiError("Failed to add pet: " + response.status()) } return PetBox.fromJson(response.body()) }) } ``` ## 🗄️ 5. @sql_schema系マクロ(企業級) ### データベーススキーマベース生成 ```nyash @sql_schema("database_schema.json") box UserQueryBox { connection: DatabaseBox // 以下のメソッドが型安全に自動生成される } ``` ### 自動生成される型安全クエリビルダー ```nyash // SELECT with type safety method findByAge(min_age: IntegerBox, max_age: IntegerBox) -> Promise> { local query = "SELECT id, name, email, age FROM users WHERE age BETWEEN ? AND ?" return me.connection.query(query, [min_age, max_age]) .then(|rows| { return rows.map(|row| { return UserBox.new( row.get_int("id"), row.get_string("name"), row.get_string("email"), row.get_int("age") ) }) }) } // Fluent query builder method where(condition: QueryConditionBox) -> UserQueryBuilderBox { return new UserQueryBuilderBox(me.connection) .add_condition(condition) } // Type-safe usage local users = await user_query .where(UserQuery.age.greater_than(18)) .where(UserQuery.name.like("%john%")) .orderBy(UserQuery.created_at.desc()) .limit(10) .execute() // Promise> ``` ## 🎨 6. @html_dsl系マクロ(表現力デモ) ### HTML生成DSL ```nyash @html_dsl box WebPageBox { title: StringBox = "My Page" users: ArrayBox // computed: HTML生成 content: StringBox { html { head { title { me.title } meta(charset="utf-8") } body { div(class="container") { h1 { "User List" } ul(class="user-list") { for user in me.users { li(class="user-item") { span(class="name") { user.name } span(class="age") { "Age: " + user.age } } } } } } } } } ``` ### 自動生成されるHTML Builder ```nyash // HTML builder methods method html(content: () -> StringBox) -> StringBox { return "" + content.call() + "" } method div(attributes: MapBox, content: () -> StringBox) -> StringBox { local attrs = me.build_attributes(attributes) return "" + content.call() + "" } method build_attributes(attrs: MapBox) -> StringBox { local result = "" attrs.each_pair(|key, value| { result = result + " " + key + "=\"" + value + "\"" }) return result } ``` ## 🚀 マクロの革新的特徴 ### 1. Property System完全統合 - **stored/computed/once/birth_once** 全てでマクロ適用可能 - **リアルタイム更新**: ファイル変更でマクロ再展開 ### 2. Box-First一貫性 - **MacroBox**: マクロ自体が一等市民のBox - **型安全性**: `MacroBox` ### 3. Visual Development - **`nyash --expand`**: 展開結果の可視化 - **`NYASH_MACRO_TRACE=1`**: ステップバイステップ追跡 ### 4. 段階的導入 - **最小MVP**: @derive(Equals)から開始 - **実用拡張**: @validate, @config_schema追加 - **高機能化**: @api_client, @sql_schema実装 --- **これらのマクロ例により、Nyashは日常的な開発から企業級アプリケーションまで、全レベルでの生産性革命を実現する。** *Property System × Macro System統合により、他言語では不可能な表現力と実用性を両立。*