elixir-meta-programming について
関数では実現できない構文やコンパイル時処理が必要な場合に、Elixir のマクロと宣言型 DSL を書くためのスキルです。quote の衛生性、DSL 生成、コンパイル時検証に関するルールを扱います。
主な機能
- 01マクロ設計と実行時関数への委譲
- 02quote の評価と衛生性
- 03宣言型 DSL の構築
- 04コンパイル時検証とエラー位置特定
活用シーン
- 01Elixir マクロの実装
- 02宣言からのモジュールコード生成
- 03マクロの評価と衛生性のレビュー
- 04DSL エラーの呼び出し元での報告
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill elixir-meta-programmingインストール後、Claude Code で/elixir-meta-programmingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdmetadata.jsonassets/templates/_template.mdreferences/_sections.mddsl-accumulate-attributes.mddsl-introspection-function.mddsl-unquote-fragments.mddsl-using-minimal.mdmacro-defguard-for-guards.mdmacro-thin-delegate-runtime.mdquote-bind-quoted-single-eval.mdquote-escape-runtime-data.mdquote-rely-on-hygiene.mdvalid-fail-at-compile-time.mdvalid-locate-errors-at-caller.md詳細
Elixir のメタプログラミングと DSL
Elixir のマクロや宣言型 DSL を正しく構築する方法です。マクロを使う必要が本当にあり、通常の関数では実現できないケースを対象としています。各ルールは、モデルが quote/unquote、__using__、@before_compile を書き始めたときに陥りがちな、具体的な誤ったデフォルトを正します。ここでは、モデルがすでに知っているマクロの基本は繰り返しません。
まず、マクロは本当に必要ですか?
デフォルトの答えはいいえです。まずは高階関数、ビヘイビア、またはデータとインタープリターを検討してください。この判断はこのスキルの役割ではありません。関連する兄弟スキルで扱っているため、このスキルを開く前に適用してください。
staff-level-elixir→data-functions-over-macros(まず関数で解決する)adversarial-elixir→meta-functions-not-macro-dsl、meta-use-is-not-import、meta-no-compile-time-coupling
マクロが正当化されるのは、関数では実現できないものが必要な場合に限られます。新しい構文、引数を評価するかどうかや評価タイミングの制御、またはコンパイル時に存在する必要があるコード(スキーマのコンパイル、宣言リストからの節の生成など)が該当します。そのしきい値を超えたら、このスキルに従って正しく実装してください。
適用する場面
- マクロを書くとき —
quoteブロックに含めるものとランタイム関数に含めるものを決め、引数の評価方法を扱う - 宣言型 DSL を構築するとき — 宣言を収集してモジュールを生成する
schema/spec/route/workflowブロック use MyDSLを組み込むとき —__using__で挿入すべきものと、@before_compileに置くべきものを決める- コンパイル時に宣言リストから関数や節を生成するとき
mix compileで DSL のエラーを発生させ、そのエラーがユーザーのソースを指すようにするとき- 既存のマクロ/DSL コードにおける評価、衛生性、エスケープ、コンパイル時検証のバグをレビューするとき
ルールのカテゴリー
| # | カテゴリー | プレフィックス | 対象 |
|---|---|---|---|
| 1 | マクロ設計 | macro | 単一のマクロの構成 — ランタイム関数を呼び出す薄いマクロ、ガード内で安全に使える構成には defguard |
| 2 | quote と衛生性 | quote | コンパイル時セマンティクスの落とし穴 — 複数回の評価、Macro.escape、衛生性と var! |
| 3 | DSL の構築 | dsl | ブロック DSL の構築 — 属性への蓄積と @before_compile、最小限の __using__、unquote フラグメント、イントロスペクション |
| 4 | コンパイル時検証 | valid | 適切なエラー処理 — コンパイル中に検証し、呼び出し元の行でエラーを示す |
クイックリファレンス
1. マクロ設計
macro-thin-delegate-runtime— 通常の関数を単一の呼び出しにするよう quote し、ロジックをテスト可能に保ち、各呼び出し箇所に置かないmacro-defguard-for-guards— 構成をガード内で使う必要がある場合はdefguard
2. quote と衛生性
quote-bind-quoted-single-eval—bind_quotedを使い、繰り返し使うunquote引数が一度だけ評価されるようにするquote-escape-runtime-data— 計算済みの項をquoteに挿入する前にMacro.escape/1を使うquote-rely-on-hygiene— 衛生性に頼り、名前の挿入が仕様として文書化されている場合にのみvar!を使う
3. DSL の構築
dsl-accumulate-attributes— 宣言をaccumulate: trueの属性に記録し、@before_compileで生成するdsl-using-minimal—__using__はセットアップのみを行い、生成処理は@before_compileに置くdsl-unquote-fragments— 内包表記の中でdef unquote(name)(...)を使い、宣言ごとに節を1つ出力するdsl-introspection-function— 呼び出し元がデータを読み取れるよう、__schema__形式のリフレクション関数を生成する
4. コンパイル時の検証
valid-fail-at-compile-time— 返されるquoteではなくマクロ本体で検証し、mix compile時にエラーを発生させますvalid-locate-errors-at-caller— 宣言マクロからエラーを発生させるか、__CALLER__をキャプチャして、ユーザーの行をエラー箇所として示します
使い方
判断が必要になったときに、該当するリファレンスファイルを読んでください。各ルールでは、修正対象となる誤った既定の方法を示したうえで、標準的な方法を説明します(誤った方法が実際の落とし穴となる場合に限り、「誤り/正解」の対比を示します)。
関連スキル
staff-level-elixir— Elixir/OTP/Ecto/Phoenix に関するより広範な判断スキルです。「マクロより関数を優先する」という判断基準を担いますadversarial-elixir— 不要なマクロ DSL を整理する、アーキテクチャレベルのレビューです。このスキルの診断を補完します
リファレンスファイル
| ファイル | 説明 |
|---|---|
| references/_sections.md | カテゴリーの定義と順序 |
| assets/templates/_template.md | 新しいルール用のテンプレート |
| metadata.json | バージョンとソースの参照情報 |