clojure-write について
Metabase のコントリビューター向けClojure開発スキルです。REPLを使った実装とテストを案内し、docstring、編集、モジュール境界の変更に関するプロジェクト固有の指針を示します。
主な機能
- 01利用可能な場合はclojure-mcpを優先
- 02REPLで関数を実装・テスト
- 03呼び出し側向けdocstringの指針
- 04Clojure編集とモジュール境界の確認
活用シーン
- 01小さなClojure関数の開発とテスト
- 02関数docstringの作成や修正
- 03プロジェクト規約に沿ったコード編集
MCP 対応
利用できる場合は`clojure_eval`や`clojure_edit`などのclojure-mcpツールを使い、利用できない場合は`./bin/mage`を使うよう案内します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ metabase/ metabase --skill clojure-writeインストール後、Claude Code で/clojure-writeを入力して読み込まれたか確認します。
詳細
Clojure 開発スキル
ツールの優先順位
clojure-mcp ツールが利用可能な場合(例: clojure_eval、clojure_edit)、./bin/mage -repl のようなシェルコマンドの代わりに、常にそれらを使用してください。MCP ツールは以下を提供します:
- シェルのエスケープ問題がない直接的な REPL 統合
- より良いエラーメッセージとフィードバック
- 構文エラーを防ぐ構造的な Clojure 編集
clojure-mcp が利用できない場合にのみ、./bin/mage コマンドにフォールバックしてください。
@./../_shared/development-workflow.md @./../_shared/clojure-style-guide.md @./../_shared/clojure-commands.md
REPL 駆動開発ワークフロー
- 小さく基本的な関数から始めます:
- タスクに必要な中核的な機能や機能性を特定します。
- 各機能を、独立して開発・テストできる最小で最も基本的な関数に分解します。
- REPL で書いてテストします:
- 各小さな関数のコードを直接 REPL(Read-Eval-Print Loop)で書きます。
- 典型的なユースケースや関連するエッジケースを含む多様な入力で徹底的にテストし、期待どおりに動作することを確認します。
- ソースコードに統合します:
- 関数が REPL で正しく動作したら、REPL 環境からソースコードファイル(例: 適切な名前空間内)に移動します。
- 徐々に複雑さを増していきます:
- テスト済みの基本的な関数を基に、より複雑な関数やコンポーネントを作成します。
- 小さな関数を組み合わせ、新しい組み合わせごとに REPL でテストして、正しさを段階的に検証します。
- 依存関係のテストを確実に行います:
- すべての関数が、他の関数から依存される前に、REPL で完全にテストされていることを確認します。
- これにより、アプリケーションの各レイヤーが、その上に構築する前に信頼できるものになります。
- REPL を最大限に活用します:
- さまざまなアプローチを試し、素早く反復し、コードに関する即時のフィードバックを得るための主要なツールとして REPL を使用します。
- 関数型プログラミングの原則に従います:
- 関数を小さく、焦点を絞り、組み合わせ可能に保ちます。
- 不変性、高階関数、標準ライブラリなど、Clojure の関数型プログラミング機能を活用して、簡潔で効果的なコードを書きます。
コードを評価する方法
ボトムアップ開発ループ
- コードをファイルに書きます。
- ファイルの名前空間を評価し、以下で正しくロードされることを確認します:
./bin/mage -repl --namespace metabase.app-db.connection
- テスト入力で名前空間内の関数を呼び出し、出力が正しいことを確認します
deftestとisを使って、これらの REPL セッションの試行をそのまま実際のテストケースにコピーしても構いません。 - これらの関数が良好であることがわかったら、1 に戻り、それらを構築する必要があるタスクに組み込みます。
ドキュメント文字列の書き方
ドキュメント文字列は呼び出し元との契約であり、実装者の日記ではありません。関数が何を行い、何を受け取り、何を返し、何をスローし、呼び出し元が守るべき事前条件や不変条件は何かを述べます。これらの保証と要件はそこに属します — まさに呼び出し元が IDE で表面化される必要があるものだからです。
ドキュメント文字列に実装の文脈を見つけた場合、デフォルトは削除ではなく移設です — 本文の中で実際に関連する箇所のインラインコメントに移動させます。その文脈は往々にして本当に価値があり、ただ場所が間違っているだけです(呼び出し元が読む必要はなく、その行に立つ実装者が読むべきです)。削除してよいのは、それが与太話である場合だけです。自己賛美、明らかなことの繰り返し、または期待されるデフォルトであるプロパティを文書化している場合です。
最後のケースについて — 「サポートされているすべての appdb にわたってポータブル」のようなプロパティを語ることに一文の価値はありません。もしポータブルでなければ、それはバグであるか、呼び出し元が各ケースを自分で処理しなければならないことを意味します — そしてその場合は、文書化すべきなのはそのプロパティの欠如です。期待からの逸脱を文書化し、期待への適合を文書化してはいけません。
ヒューリスティック — ある文がドキュメント文字列に居場所を得るのは、次の両方のテストを通過した場合だけです:
-
書き換えテスト(必要だが十分ではない): 同一の契約を持つ別の実装に本文を書き換えてもその文が偽にならないなら、その文は実装を記述しており契約を記述していません。本文の中で適用される箇所のインラインコメントに移設してください。
-
所有権テスト: その文がこの関数が所有していないコードについての事実 — 呼び出し先の振る舞い、ライブラリの保証 — を述べているなら、書き換えに関係なく自明に生き残ります。だからこそ書き換えテストだけでは不十分なのです。もしこの本文がその事実に依存しているなら、それは実装の文脈です: 呼び出し箇所に移設してください。ここで何もそれに依存していないなら、それは他人のコードについての与太話です: 削除し、呼び出し先自身のドキュメント文字列に答えさせてください。
各事実は一度だけ述べてください。重複した記述は事前に陳腐化したコメントです: 事実が変わると、一つのコピーが更新され残りは静かに腐ります。これは自分が所有するコード内でも当てはまります — 自身のマルチメソッドを再要約する名前空間ドキュメント文字列、リトライの振る舞いについて同じ段落を抱える三つの兄弟関数。事実には一つの住処を与え、他の場所ではそれを言い換えるのではなく名指しさせてください。
複数行のドキュメント文字列は禁止されていません — コードが対処しなければならなかった、真に自明でない制約は説明する価値があるかもしれません。しかし慎重に。失敗モードは細かすぎる記述です。複数段落の説明的なドキュメント文字列を書きたくなったら、まずユーザーに確認してください。そして散文よりもテストを好んでください: 将来の読者が「そんなやり方は馬鹿げている」と考えて変更したなら、テストが失敗してその理由を伝えるべきです。その破壊が繰り返し起こるなら、それこそコメントが必要だったというシグナルです。
編集の重要なルール
- Clojure コードを編集するときは括弧の数に注意してください
- Clojure コードへの変更のたびに、
-check-readableで可読性を検証してください - すべてのファイルを改行で終えてください
- 表形式のコードを編集するとき、列が揃っている場合は、揃えたままにするよう努めてください
- 後に何も続かない行にスペースを置くことは許可されていません
- モジュールの境界を変更した後(
src名前空間の追加・削除・名前変更、モジュールをまたぐrequireや:model/X参照、または新しいモジュール)、./bin/mage fix-modules-configを実行して.clj-kondo/config/modules/config.ednを再生成し、metabase.core.modules-testをグリーンに保ってください。何もずれていなければ何もしません。プロジェクトのCLAUDE.mdの「Module Boundaries」を参照してください。