Можете ли вы дать мне несколько реальных примеров макроса ->? - PullRequest
3 голосов
/ 22 октября 2009

Кажется, это мощный макрос, но я не могу применить его ни к чему, кроме глупых примеров. Можете ли вы показать мне его реальное использование?

Спасибо!

Ответы [ 3 ]

9 голосов
/ 23 октября 2009

Сравнить:

user> (:baz (:bar (:foo {:foo {:bar {:baz 123}}})))
123
user> (java.io.BufferedReader. (java.io.FileReader. "foo.txt"))
#<BufferedReader java.io.BufferedReader@6e1f8f>
user> (vec (reverse (.split (.replaceAll (.toLowerCase "FOO,BAR,BAZ") "b" "x") ",")))
["xaz" "xar" "foo"]

до:

user> (-> {:foo {:bar {:baz 123}}} :foo :bar :baz)
123
user> (-> "foo.txt" java.io.FileReader. java.io.BufferedReader.)
#<BufferedReader java.io.BufferedReader@7a6c34>
user> (-> "FOO,BAR,BAZ" .toLowerCase (.replaceAll "b" "x") (.split ",") reverse vec)
["xaz" "xar" "foo"]

-> используется, когда требуется краткий способ вложения вызовов. Это позволяет вам перечислить вызовы в порядке их вызова, а не наизнанку, что может быть более читабельным. В третьем примере обратите внимание на расстояние между некоторыми аргументами и функцией, к которой они принадлежат; -> позволяет более аккуратно группировать аргументы и вызовы функций. Поскольку это макрос, он также работает для вызовов Java, что приятно.

-> не такой мощный, просто время от времени экономит вам несколько паренов. Использовать его или нет - это вопрос стиля и читабельности.

Посмотрите на нижнюю часть clojure.zip , чтобы найти примеры того, как это полезно.

(-> dz next next next next next next next next next remove up (append-child 'e) root)
5 голосов
/ 23 октября 2009

Взято из вики Я всегда находил этот пример впечатляющим:

user=> (import '(java.net URL) '(java.util.zip ZipInputStream))
user=> (-> "http://clojure.googlecode.com/files/clojure_20081217.zip"
           URL. .openStream ZipInputStream. .getNextEntry bean :name)

Как сказал Брайан - это не «полезно», а «другой стиль». Я нахожу для всех java-операций эту форму «начинай с X», затем делай Y и Z ... более читабельными, чем Z-Y из X.

В основном у вас есть 4 варианта:

; imperative style named steps:
(let [X something
      b (Y X)
      c (Z b)] c)

; nested calls
(Z (Y X))

; threaded calls
(-> X Y Z)

; functional composition
((comp Z Y) X)

Я нахожу -> действительно сияет для взаимодействия с Java, но избегайте его в других местах.

2 голосов
/ 04 ноября 2009
(defn search-tickets-for [term]
  (-> term search zip-soup first :content
    ((partial filter #(= :body (:tag %)))) first :content
    ((partial filter #(= :div (:tag %))))
    ((partial filter #(= "content" ((comp :id :attrs) %))))
    ((partial map :content)) first ((partial map :content))
    ((partial map first)) ((partial filter #(= :ul (:tag %)))) first :content
    ((partial map :content))
    ((partial map first))
    ((partial mapcat :content))
    ((partial filter #(= :h4 (:tag %))))
    ((partial mapcat :content))
    ((partial filter #(= :a (:tag %))))
    ((partial mapcat :content))))

clojurebot из #clojure использует это для поиска билетов на ассембле

...