mcpField
E
elixir-idioms

elixir-idioms

github.com/oliver-kriska開発57148 回インストール6 日前に更新
リポジトリ

elixir-idioms について

elixir-idioms は、BEAM に適したパターンで慣用的な Elixir コードを書くためのリファレンススキルです。制御フロー、エラー処理、プロセス、OTP の規則や判断ガイド、例を提供します。

主な機能

  1. 01パターンマッチとパイプの活用
  2. 02エラー処理規約の選択
  3. 03プロセスと OTP コンポーネントの選定
  4. 04Elixir のよくある落とし穴の回避
  5. 05テーマ別リファレンスの参照

活用シーン

  1. 01Elixir コードの慣用パターンの確認
  2. 02関数、Agent、GenServer、Task の選択
  3. 03想定内外のエラー処理
  4. 04長期稼働プロセスの監督設計

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/oliver-kriska/claude-elixir-phoenix --skill elixir-idioms

インストール後、Claude Code で/elixir-idiomsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
anti-patterns.md
elixir-118-features.md
elixir-120-type-system.md
error-handling.md
mix-tasks.md
otp-patterns.md
pattern-matching.md
troubleshooting.md
with-and-pipes.md

詳細

Elixir のイディオム

BEAM を考慮したパターンを使って、慣用的な Elixir コードを書くためのリファレンスです。

鉄則 — 決して破ってはいけません

  1. 実行時の理由がないプロセスを作らない — プロセスは並行処理、状態、分離をモデル化するものであり、コードの構造を表すものではありません
  2. メッセージはコピーされる — メッセージは小さく保ちます(64 バイトを超えるバイナリを除く)
  3. ガードでは and/or/not を使う — ガードで短絡評価演算子は使わないでください(ガードではブール値のオペランドが必要です)
  4. 外部データにはチェンジセットを使う — ユーザー入力には cast/4、内部データには change/2 を使います
  5. 外部コードに対してのみ rescue を使う — 制御フローに rescue を使わないでください
  6. アトムを動的に作成しない — String.to_atom(user_input) はメモリーリークを引き起こします(アトムは GC の対象になりません)
  7. コンパイル時に読み込むファイルには @external_resource を使う — コンパイル時にファイルを読み込むモジュールでは、必ず @external_resource を宣言します
  8. 長時間実行されるプロセスはすべて監督下に置く — 本番環境で GenServer.start_link/Agent.start_link を単独で使わないでください。監督ツリーを使います
  9. サードパーティライブラリの API をラップする — 外部依存関係は必ずプロジェクト所有のモジュールの背後にファサードを設けます。これにより、呼び出し元に手を加えずに差し替えられます
  10. Mix タスクでは必要なものだけを起動する — Mix.Task.run("app.config") + Application.ensure_all_started/1 を使い、Mix.Task.run("app.start") は使わないでください(エンドポイントのポートや Oban の処理などを含むツリー全体が起動します)
  11. プロセスを生成する前にロケールを取得する — Gettext/CLDR のロケールはプロセス単位です。呼び出し元で読み取り、明示的に渡してください。生成された Task/GenServer はデフォルトのロケールで開始します

BEAM のアーキテクチャ(Elixir がこのように動作する理由)

  • プロセスは軽量です(2.6KB) — 並行処理や分離のために積極的に生成します
  • メモリーは完全に分離されています — 共有状態がないため、ロックは不要です
  • メッセージはコピーされます(64 バイトを超えるバイナリを除く)— メッセージは小さく保ちます
  • プロセスごとの GC — グローバルな GC 停止がありません
  • 「クラッシュさせる」 — スーパーバイザーが既知の正常な状態に再起動します

基本原則

  1. 条件分岐よりパターンマッチを優先する — まず関数ヘッド、次に case、最後に cond を使います
  2. 想定される失敗にはタグ付きタプルを使う — 想定されるエラーには {:ok, _}/{:error, _} を使い、バグは raise します
  3. データ変換にはパイプ演算子を使う — データから始め、単独の呼び出しにはパイプを使いません
  4. クラッシュさせる — 想定されるエラーは処理し、想定外のエラーではクラッシュさせます
  5. 暗黙より明示を優先する — 意図を明確にします

すぐに使える判断フロー

制御フロー
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) == 0list == [] または 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 conditionif !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+)

コメント