3

私はleinプロジェクトを持っています(cascalogを使用していますが、それは特に重要ではありません)。ファイルへのパスなどのプロパティを外部化しようとしているので、次のようなコードになります。

(defn output-tap [path] (hfs-textline (str (get-prop :output-path-prefix) path) :sinkmode :replace))

(def some-cascalog-query 
    (<- [?f1 ?f2 ?f3] 
        ((output-tap (get-prop :output-path)) ?line)
        (tab-split ?line :> ?f1 ?f2 ?f3)))

上記の例では、関数get-propが存在すると仮定します。これは、標準のJavaを使用してプロパティ値を読み取るだけです(この例に基づいて:データ構造としてclojureに構成ファイルをロードします)。

これで、プロパティ値をロードするmainメソッドができました。たとえば、次のようになります。

(defn -main [& args] (do (load-props (first args)) (do-cascalog-stuff)))

しかしlein uberjar、コンパイル時エラーが発生すると、次のようになります。

Caused by: java.lang.IllegalArgumentException: Can not create a Path from an empty string
at org.apache.hadoop.fs.Path.checkPathArg(Path.java:82)
at org.apache.hadoop.fs.Path.<init>(Path.java:90)
at cascading.tap.hadoop.Hfs.getPath(Hfs.java:343)

defは常に(実行時ではなく)コンパイル時に評価されますか?それとも私はこのエラーを誤解していますか?

4

2 に答える 2

3

それで、実行時にプロパティルックアップを実行したいですか?some-cascalog-queryそうです、関数またはマクロとして定義する必要があります。ベアdefを使用すると、変数が逆参照されたときではなく、コードがロードされたときに式が評価されます。

これは、REPLで非常に簡単に説明できます。

user=> (def foo (do (println "Hello, world!") 1))
Hello, world!
#'user/foo
user=> foo
1

ドキュメントから(私の強調):

(def symbol init?)

シンボルの名前と現在の名前空間の値( ns )の名前空間を使用して、グローバル変数を作成およびインターンまたは検索します。initが指定されている場合、それが評価され、varのルートバインディングが結果の値に設定されます。

于 2012-06-19T16:35:56.307 に答える
0

(get-prop :output-path) (get-prop :output-path-prefix)そのエラーは、によって空の文字列にラップされているものを何も返さないように見えますstr。おそらくプロパティが見つかりませんか?

get-propは期待どおりに機能しますか?

defの理解は正しいです。これはコンパイル時であり、(通常は)ランタイムではありません。

于 2012-06-19T16:11:33.397 に答える