2011-08-11 6 views
3

私はclojureの新機能です.clojure.contrib.strintを使用してURLを作成しようとしています。例えば私は、Google検索のためにこれを使用する場合があります:clojure.contrib.strintを他の場所で定義された文字列で使用する

(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}"))を試しましたが、私は自分のレットの文脈でそのフォームを評価する方法を理解できません。私はsearch_url関数に文字列を置くことができますが、それは私には劣っていると感じています。これに対する答えがClojureを少し良く理解するのに役立つことを願っています。

おかげ

答えて

0

は私が<<on 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はプライベートなので、いくつかのコピーを貼り付ける必要がありますが、最終的な使用法は非常にクールです。

+3

'query'が例えばあるときにこれが分解します。 letローカル。 '<<'はコンパイル時に拡張するように明示的に設計されています。ランタイムではありません。必要なら 'format'を使います。または、 '(<<"〜{baseurl}?hl =〜{language}&=〜{queryitem} ")'の部分からクエリ文字列を作成します。 – kotarak

+0

@kotarak:sweet;) –

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}"))) 
関連する問題