アロー マクロ (->) は、n 番目の形式の値が最初の引数として n+1 番目の形式に挿入されるように、その引数を書き換えるだけです。あなたが書いていることは以下と同等です:
(case
(.compile
(.newXPath (XPathFactory/newInstance))
xpath)
return-type
:node-list (.evaluate document XPathConstants/NODESET)
:node (.evaluate document XPathConstants/NODE)
:number (.evaluate document XPathConstants/NUMBER)
一般に、 を使用して 3 つのフォームのいずれかをテール フォームとして事前に選択しlet
、それをスレッド マクロの最後にスレッド化することができます。そのようです:
(defn eval-xpath [document xpath return-type]
(let [evaluator (case return-type
:node-list #(.evaluate % document XPathConstants/NODESET)
:node #(.evaluate % document XPathConstants/NODE)
:number #(.evaluate % document XPathConstants/NUMBER))]
(-> (XPathFactory/newInstance)
.newXPath
(.compile xpath)
(evaluator))))
ただし、実際にやろうとしているのは、キーワードを XPathConstants の定数にマップすることです。これは、マップを使用して実行できます。次の点を考慮してください。
(defn eval-xpath [document xpath return-type]
(let [constants-mapping {:node-list XPathConstants/NODESET
:node XPathConstants/NODE
:number XPathConstants/NUMBER}]
(-> (XPathFactory/newInstance)
.newXPath
(.compile xpath)
(.evaluate document (constants-mapping return-type)))))
キーワードから定数へのマッピングがあるので、Clojure のデータ構造を使用してそれを表現します。さらに、スレッド化マクロの真価は、xpath のコンパイルに役立ちます。ローカル スコープの名前を使用しているデータに、何をしているかを追跡できるようにすることを恐れないでください。また、実際には収まりたくないものをスレッド化マクロに押し込もうとするのを避けるのにも役立ちます。