3

我是 clojure 的新手,我正在尝试使用 clojure.contrib.strint 来构建一个 URL。例如,我可能会将其用于 google 搜索:

(def search_base_url "http://www.google.com/search?hl=en&q=~{query}")

(defn search_url [search_term]
  (let [query (.replaceAll search_term "\\s+" "+")]
    (<< search_base_url)))

但这给了我编译器错误:
错误:java.lang.RuntimeException:java.lang.RuntimeException:java.lang.IllegalArgumentException:找不到匹配的方法:类clojure.lang.Symbol的indexOf。
我认为 strint 使用 indexOf 几次,所以我似乎没有给 << 函数它想要的东西。

我也试过(def search_base_url '(<< "http://myurl.com?~{params}"))了,但是我不知道如何在我的 let 上下文中评估该表单。我可以把字符串放在 search_url 函数中,但这感觉不如我,我希望这个问题的答案能帮助我更好地理解 clojure。

谢谢

4

2 回答 2

1

问题是,“<<”宏需要一个字符串,而不是评估为字符串的东西。也就是说,它尝试在名为“search_base_url”的符号上调用 .indexOf,而不是在其值上。

所以解决这个问题的一种方法是:

(defn search-url [search-term]
  (let [query (.replaceAll search-term "\\s+" "+")]
    (<< "http://www.google.com/search?hl=en&q=~{query}")))
于 2011-08-17T15:08:24.643 回答
0

我查看了<< github上的源代码......我也无法让它以你想要的方式工作。

如果你像这样重写宏:

(defmacro <<<
    [string]
      `(apply str (map #(eval %) (interpolate ~string))))

然后

(def query "queryitem")
(def basesearch "http://www.google.com/search?hl=en&q=~{query}")

(<<< basesearch)

将返回

"http://www.google.com/search?hl=en&q=queryitem"

这就是你想要的。原因是:

 (interpolate basesearch)

返回一个不执行序列评估的惰性序列:

 ("http://www.google.com/search?hl=en&q=" query "")

query符号永远不会在<<宏中求值并按原样返回。

由于silent-readinterpolate是私有的,您将不得不做一些复制粘贴,但最终的使用非常酷。

于 2011-08-12T02:23:08.437 回答