Clojure

REPLでのプログラミング:トラブルシューティング

定義されていないVarの呼び出し

症状

user=> my-nonexistent-name
Syntax error compiling at (REPL:0:0).
Unable to resolve symbol: my-nonexistent-name in this context

説明

  • Var名にタイプミスがある可能性があります。たとえば、`my-nonexistent-name` ではなく `my-non-existent-name` と書くべきだったかもしれません。

  • REPLで`my-nonexistent-name`を定義するのを忘れている可能性があります(たとえば、`def`または`defn`を使用)。これは、コードファイルに`(def my-nonexistent-name …​)`と書いてREPLで評価するのを忘れた場合に発生する可能性があります。

  • `my-non-existent-name`を定義したが、別の名前空間で定義した可能性があります。`myapp.ns23/my-non-existent-name`と書くか、名前空間`myapp.ns23/my-non-existent-name`に切り替える必要があります。

存在しない名前空間エイリアスの使用

症状

user=> ns3/foo-bar
Syntax error compiling at (REPL:0:0).
No such namespace: ns3

説明

  • 名前空間エイリアスにタイプミスがある可能性があります。たとえば、`ns3/foo-bar`ではなく`n3/foo-bar`と書くべきだったかもしれません。

  • 現在の名前空間で`ns3`エイリアスを定義したことがない可能性があります。`(require '[myapp.ns3 :as ns3])`を評価することで修正できます。

  • `ns3`エイリアスを定義しましたが、REPLが現在存在する名前空間とは異なる名前空間で定義した可能性があります。

ロードされていない名前空間の参照

症状

$ clj
Clojure 1.10.0
user=> clojure.set/union
Syntax error (ClassNotFoundException) compiling at (REPL:0:0).
clojure.set

説明

REPLでまだ作成されていない名前空間を使用しています。エラーメッセージ('ClassNotFoundException')はこの場合特に紛らわしいことに注意してください。理由は、Clojureコンパイラが`clojure.set`という名前のロードされた名前空間を見つけられず、clojure.setをJavaクラスとして解釈しようとしているためです。解決策は、clojure.setライブラリがロードされていることを確認することです。

存在しない名前空間をrequireしようとする

症状

user=> (require '[a.b.c])
Execution error (FileNotFoundException) at user/eval161 (REPL:1).
Could not locate a/b/c__init.class, a/b/c.clj or a/b/c.cljc on classpath.

**説明:** Clojureは`a.b.c`という名前の既存の名前空間を見つけられず、次にクラスパスでそれを定義するライブラリを検索し、最終的に上記の例外で失敗しました。原因はさまざまです。

  • 名前空間にタイプミスがあるかもしれません。

  • ライブラリをクラスパスに追加するのを忘れている可能性があります。これは通常、プロジェクトの依存関係の構成(たとえば、`deps.edn`または`project.clj`ファイル)にライブラリを追加し、場合によっては(プロジェクト管理ツールに応じて)インストールコマンド(たとえば、`lein deps`)を実行することで行われます。

  • ライブラリをクラスパスに追加しましたが、REPLを起動した後だった可能性があります。この場合は、REPLを再起動する必要があります。