2012-06-19 3 views
3

J'ai un projet lein (en utilisant cascalog - mais ce n'est pas particulièrement important). Je suis en train de propriétés comme des chemins extérioriser aux fichiers, donc je me retrouve avec un code qui ressemble à ceci:comportement clojure de def

(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))) 

Dans l'exemple ci-dessus, assumer la fonction get-prop existe; il utilise simplement java standard pour lire une valeur de propriété (basée sur cet exemple: loading configuration file in clojure as data structure).

Maintenant, j'ai une méthode principale qui charge les valeurs de propriété, par ex. quelque chose comme:

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

Mais quand je lein uberjar je reçois une erreur de compilation en disant:

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) 

sont-defs compilent toujours le temps évalué (plutôt que l'exécution évaluée)? Ou ai-je mal compris cette erreur?

Répondre

3

Donc, vous voulez que la recherche de propriété se produise au moment de l'exécution? Alors oui, vous devrez définir some-cascalog-query comme une fonction ou une macro. Un def nu provoque l'évaluation de l'expression lorsque le code est chargé, pas lorsque la var est déréférencée.

Ceci peut être illustré assez simplement dans le REPL:

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

De la documentation (Souligné par l'auteur): (symbole DEF initialisation)

Crée et stagiaires ou localise une variable globale avec le nom de symbole et un espace de nom de la valeur de l'espace de nom courant (ns). Si init est fourni, il est évalué et la liaison racine de var est définie sur la valeur résultante.

0

cette erreur ressemble à (get-prop :output-path)(get-prop :output-path-prefix) est retournent rien qui est enveloppé dans une chaîne vide par str. Peut-être que la propriété n'est pas trouvée?

est-ce que le travail get-prop fonctionne comme prévu?

votre compréhension de defs est correcte, ils sont temps de compilation, pas (habituellement) runtime.