2

実行時に丸呑みされる特定のデータ ファイルに依存する webapp に取り組んでいます。データファイルが存在しないと、コンパイルできないようです。どうしてこれなの?

これは私のcore.cljにあります

(def my-data (slurp "my-file.txt"))

次に、コンパイルしようとすると:

$ lein ring war

この例外が発生します

Exception in thread "main" java.io.FileNotFoundException: my-file.txt (No such file or directory), compiling:(core.clj:24:28)

どうすれば自分の戦争をコンパイルできますか? コンパイル時にファイルを丸呑みしたり、存在を確認したりする必要はありません。前もって感謝します!

[アップデート]

これは、war ファイルのパッケージ化またはリングに固有のものではありません。次に例を示します。

(ns slurp-test.core
    (:gen-class))

(def x (slurp "/tmp/foo.txt"))

(defn -main [& args]
    (println x))

それで:

 $ lein uberjar
 Compiling slurp-test.core
 (ns slurp-test.core
 Exception in thread "main" java.io.FileNotFoundException: /tmp/foo.txt (No such file or directory), compiling:(core.clj:4:8)

どうすればこれを修正できますか?

4

1 に答える 1

5

Clojure ソース ファイルのコンパイルには、すべてのトップレベル フォームの評価が含まれます。これは、期待されるセマンティクスをサポートするために実際に厳密に必要です

コードを AOT コンパイルすると、最上位のフォームはコンパイル時に評価され、コンパイルされたコードが読み込まれる実行時に再度評価されます。

このため、トップレベルにあるコードに副作用を引き起こすことは、一般的には良い考えではありません。アプリで初期化が必要な場合は、関数 (通常は-main) によって実行する必要があります。


1マクロは、マクロとしてマークされた Var に存在する関数です ( :macro trueVar のメタデータ内にあり、このエントリを追加するsetMacroメソッドがあります)。clojure.lang.Varマクロは、コンパイラで明確に使用できる必要があるため、コンパイル時にロードする必要があります。さらに、展開を計算する際に、マクロ関数は、マクロ以外の関数を呼び出したり、マクロが呼び出されるポイントの前に発生するトップレベル コードを評価した結果として得られる任意の Vars の値を利用したりする場合があります。これらの機能を削除すると、マクロ機能がかなり損なわれます。

于 2013-06-05T01:27:38.507 に答える