2012-06-10 2 views
5

Я новичок в Clojure, и я зациклился на том, как «развернуть» необязательные аргументы функции, чтобы их можно было отправить другой функции, которая использует необязательные аргументы (но хочет, чтобы те args как ключевые слова, а не ключевые слова).Clojure: передать расширенные дополнительные аргументы

Я разбора XML и если я жестко закодировать значения, как показано ниже моя функция работает, он ходит по XML и находит значение «название»:

; zd was required like this 
[clojure.data.zip.xml :as zd] 
; ... 
(defn get-node-value [parsed-xml & node-path] 
    (zd/xml-> (zip/xml-zip parsed-xml) :item :title zd/text)) 

(get-node-value parsed-xml) 

То, что я хочу сделать, это использовать «узел -path», чтобы передать любое количество ключевых слов, но когда написано ниже он приходит в качестве последовательности ключевых слов, поэтому он бросает исключение:

(defn get-node-value [parsed-xml & node-path] 
    (zd/xml-> (zip/xml-zip parsed-xml) node-path zd/text)) 

(get-node-value parsed-xml :item :title) 
; ClassCastException clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn clojure.data.zip/fixup-apply (zip.clj:73) 

спасибо!

ответ

8

Я думаю, что вы ищете применения (http://clojuredocs.org/clojure_core/clojure.core/apply)

(defn get-node-value [parsed-xml & node-path] 
    (let [params (concat node-path [zd/text])] 
    (apply zd/xml-> (zip/xml-zip parsed-xml) params))) 
3

Может быть вы хотите:

(defn get-node-value [parsed-xml & node-path] 
    (zd/xml-> (zip/xml-zip parsed-xml) ((apply comp (reverse node-path))) zd/text)) 

я могу 't проверить выше, поэтому я работаю по аналогии:

(-> {:a {:c 1}, :b 2} ((apply comp (reverse [:a :c])))) 
1 

Однако, если dAni's решение работает, игнорируйте меня!

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