elixir-idioms について
elixir-idioms は、BEAM に適したパターンで慣用的な Elixir コードを書くためのリファレンススキルです。制御フロー、エラー処理、プロセス、OTP の規則や判断ガイド、例を提供します。
主な機能
- 01パターンマッチとパイプの活用
- 02エラー処理規約の選択
- 03プロセスと OTP コンポーネントの選定
- 04Elixir のよくある落とし穴の回避
- 05テーマ別リファレンスの参照
活用シーン
- 01Elixir コードの慣用パターンの確認
- 02関数、Agent、GenServer、Task の選択
- 03想定内外のエラー処理
- 04長期稼働プロセスの監督設計
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ oliver-kriska/ claude-elixir-phoenix --skill elixir-idiomsインストール後、Claude Code で/elixir-idiomsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/anti-patterns.mdelixir-118-features.mdelixir-120-type-system.mderror-handling.mdmix-tasks.mdotp-patterns.mdpattern-matching.mdtroubleshooting.mdwith-and-pipes.md詳細
Elixir のイディオム
BEAM を考慮したパターンを使って、慣用的な Elixir コードを書くためのリファレンスです。
鉄則 — 決して破ってはいけません
- 実行時の理由がないプロセスを作らない — プロセスは並行処理、状態、分離をモデル化するものであり、コードの構造を表すものではありません
- メッセージはコピーされる — メッセージは小さく保ちます(64 バイトを超えるバイナリを除く)
- ガードでは
and/or/notを使う — ガードで短絡評価演算子は使わないでください(ガードではブール値のオペランドが必要です) - 外部データにはチェンジセットを使う — ユーザー入力には
cast/4、内部データにはchange/2を使います - 外部コードに対してのみ rescue を使う — 制御フローに rescue を使わないでください
- アトムを動的に作成しない —
String.to_atom(user_input)はメモリーリークを引き起こします(アトムは GC の対象になりません) - コンパイル時に読み込むファイルには @external_resource を使う — コンパイル時にファイルを読み込むモジュールでは、必ず
@external_resourceを宣言します - 長時間実行されるプロセスはすべて監督下に置く — 本番環境で
GenServer.start_link/Agent.start_linkを単独で使わないでください。監督ツリーを使います - サードパーティライブラリの API をラップする — 外部依存関係は必ずプロジェクト所有のモジュールの背後にファサードを設けます。これにより、呼び出し元に手を加えずに差し替えられます
- Mix タスクでは必要なものだけを起動する —
Mix.Task.run("app.config")+Application.ensure_all_started/1を使い、Mix.Task.run("app.start")は使わないでください(エンドポイントのポートや Oban の処理などを含むツリー全体が起動します) - プロセスを生成する前にロケールを取得する — Gettext/CLDR のロケールはプロセス単位です。呼び出し元で読み取り、明示的に渡してください。生成された Task/GenServer はデフォルトのロケールで開始します
BEAM のアーキテクチャ(Elixir がこのように動作する理由)
- プロセスは軽量です(2.6KB) — 並行処理や分離のために積極的に生成します
- メモリーは完全に分離されています — 共有状態がないため、ロックは不要です
- メッセージはコピーされます(64 バイトを超えるバイナリを除く)— メッセージは小さく保ちます
- プロセスごとの GC — グローバルな GC 停止がありません
- 「クラッシュさせる」 — スーパーバイザーが既知の正常な状態に再起動します
基本原則
- 条件分岐よりパターンマッチを優先する — まず関数ヘッド、次に
case、最後にcondを使います - 想定される失敗にはタグ付きタプルを使う — 想定されるエラーには
{:ok, _}/{:error, _}を使い、バグは raise します - データ変換にはパイプ演算子を使う — データから始め、単独の呼び出しにはパイプを使いません
- クラッシュさせる — 想定されるエラーは処理し、想定外のエラーではクラッシュさせます
- 暗黙より明示を優先する — 意図を明確にします
すぐに使える判断フロー
制御フロー
Need patterns? → case (or function heads)
Multiple operations? → with
Boolean conditions? → cond (multiple) or if (single)
エラー処理
Expected failure? → {:ok, _}/{:error, _} tuples
Unexpected/bug? → raise exception (let supervisor handle)
External library? → rescue (only here!)
OTP
Need state?
├─ No → Plain functions
├─ Simple get/update → Agent or ETS
├─ Complex messages/timeouts → GenServer
└─ One-off async → Task
すぐに使えるパターン
# Pattern match in function head
def process(%{status: :active} = user), do: activate(user)
def process(%{status: :inactive} = user), do: deactivate(user)
# with for happy path
with {:ok, user} <- get_user(id),
{:ok, order} <- create_order(user) do
{:ok, order}
end
# Task for async
Task.Supervisor.async_nolink(TaskSup, fn -> work() end)
|> Task.yield(5000) || Task.shutdown(task)
よくある落とし穴
| 誤り | 正しい方法 |
|---|---|
length(list) == 0 | list == [] または Enum.empty?(list) |
list ++ [item] | [item | list] |> Enum.reverse() |
String.to_atom(input) | String.to_existing_atom(input) |
spawn(fn -> log(conn) end) | ip = conn.ip; spawn(fn -> log(ip) end) |
unless condition | if !condition(unless は 1.18 で非推奨) |
参考資料
詳しいパターンについては、以下を参照してください。
${CLAUDE_SKILL_DIR}/references/pattern-matching.md- パターンマッチ、ガード、バイナリマッチ${CLAUDE_SKILL_DIR}/references/otp-patterns.md- GenServer、Supervisor、Task、Registry${CLAUDE_SKILL_DIR}/references/error-handling.md- タグ付きタプル、rescue、with${CLAUDE_SKILL_DIR}/references/with-and-pipes.md-withと|>を使う場面(慣用的なパターン)${CLAUDE_SKILL_DIR}/references/troubleshooting.md- 本番 BEAM のデバッグ(メモリー、パフォーマンス、クラッシュ)${CLAUDE_SKILL_DIR}/references/anti-patterns.md- よくある間違いと修正方法${CLAUDE_SKILL_DIR}/references/mix-tasks.md- Mix タスクの命名、オプション解析、シェル出力${CLAUDE_SKILL_DIR}/references/elixir-118-features.md- Duration モジュール、dbg の改善(1.18+)${CLAUDE_SKILL_DIR}/references/elixir-120-type-system.md- 段階的型チェッカー、dynamic()、検証済みバグのコンパイル時警告(1.20+、OTP 27+)
コメント
Markdown 対応