2012-06-19 4 views
3

У меня есть проект lein (с использованием cascalog - но это не особенно важно). Я пытаюсь экстернализации свойства, такие как пути к файлам, так что я в конечном итоге с кодом, который выглядит примерно так:clojure поведение 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))) 

В приведенном выше примере, предположим, что функция get-prop существует; он просто использует стандартную java для чтения значения свойства (на основе этого примера: loading configuration file in clojure as data structure).

Теперь у меня есть основной метод, который загружает значения свойств, например. что-то вроде:

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

ли DEFS всегда время компиляции вычисляется (вместо выполнения оценивается)? Или я не понимаю эту ошибку?

ответ

3

Итак, вы хотите, чтобы поиск свойств происходил во время выполнения? Тогда да, вам нужно определить some-cascalog-query как функцию или макрос. Голый def заставляет выражение оцениваться при загрузке кода, а не при разыменовании var.

Это можно проиллюстрировать довольно просто в РЕПЛ:

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

Из documentation (курсив мой): (? Защиту символ инициализации)

Создает и стажеры или находит глобальный var с именем символа и пространством имен значения текущего пространства имен (ns). Если задана функция init, она вычисляется, а корневая привязка переменной var устанавливается на результирующее значение.

0

Эта ошибка выглядит так: (get-prop :output-path)(get-prop :output-path-prefix) ничего не возвращает, которое обернуто в пустую строку str. возможно, собственность не найдена?

действительно ли работает как ожидается?

Ваше понимание defs правильно, они являются временем компиляции, а не (обычно) временем выполнения.

Смежные вопросы