使用clojure.contrib.strint和其他地方定义的字符串

时间:2011-08-11 20:56:56

标签: clojure clojure-contrib

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

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

但这给了我编译错误:
error:java.lang.RuntimeException:java.lang.RuntimeException:java.lang.IllegalArgumentException:找不到匹配的方法:class clojure.lang.Symbol的indexOf。
我认为strint使用了indexOf几次,所以不知怎的,我没有给出&lt;&lt;似乎功能它想要什么。

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

由于

2 个答案:

答案 0 :(得分:1)

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

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

(defn search-url [search-term]
  (let [query (.replaceAll search-term "\\s+" "+")]
    (<< "http://www.google.com/search?hl=en&q=~{query}")))

答案 1 :(得分:0)

我查看了<< on github的源代码......我无法按照您想要的方式工作。

BUT

如果你像这样重写宏:

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

返回一个不执行序列评估的lazy-seq:

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

永远不会在query宏中评估<<符号,并按原样返回。

由于silent-readinterpolate是私有的,您可以使用一些复制粘贴,但最终用法非常酷。