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

しかし、これは私にコンパイラエラーを与えます:
error: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: No matching method found: indexOf for class clojure.lang.Symbol.
strint は indexOf を数回使用していると思うので、どういうわけか << 関数に必要なものを与えていないようです。

も試しまし(def search_base_url '(<< "http://myurl.com?~{params}"))たが、 let のコンテキストでそのフォームを評価する方法がわかりません。文字列を search_url 関数に入れることもできますが、それは私には劣っているように感じます。これに対する答えが、clojure をもう少しよく理解するのに役立つことを願っています。

ありがとう

4

2 に答える 2

1

問題は、"<<" マクロが、文字列として評価されるものではなく、文字列を想定していることです。つまり、その値ではなく、「search_base_url」という名前のシンボルで .indexOf を呼び出そうとします。

したがって、これを修正する1つの方法は次のとおりです。

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

シーケンスの評価を実行しない lazy-seq を返します。

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

queryシンボルは<<マクロで評価されず、そのまま返されます。

silent-readinterpolateは非公開なので、コピー ペーストを行う必要がありますが、最終的な使い方は非常にクールです。

于 2011-08-12T02:23:08.437 に答える