Finding ClojureKurt Harriger     @kurtharriger
The ChallengeTwitter search url filter
Project Folder% lein new twitturlCreated new project in: /Users/kurtharriger/code/twitturl├──   README├──   project.clj├──...
project.clj(defproject twitturl "1.0.0-SNAPSHOT"  :description "Twitturl aggregator"  :dependencies [[org.clojure/clojure ...
Appleholics% brew install leiningen       Non AppleholicsFind Leiningen for Clojure onhttps://github.com/technomancy/leini...
S-Expressions Clojure: (defn fn [arg1 & more] arg1)defn is a macro used here with 3 parameters:function name, arguments, a...
S-Expressions Clojure: (defn fn [arg1 & more] arg1)defn is a macro used here with 3 parameters:function name, arguments, a...
ring framework(ns twitturl.core  (:require [com.twinql.clojure.http :as http])  (:use [ring.middleware.params])  (:use [hi...
De-structuring(defn format-tweets [json] nil) ; todo(defn handler [{{q "q"} :params}]  { :content-type "text/html"    :bod...
The Search(def url "http://search.twitter.com/search.json")   define readonly variable named url(defn search [query]  (htt...
Enter the repl% lein depsCopying 22 files to /Users/kurtharriger/code/twitturl/libCopying 17 files to /Users/kurtharriger/...
The Handler(defn format-tweets [json] nil) ; todo(defn handler [{{q "q"} :params}]  { :content-type "text/html"    :body  ...
functions(defn aslink [url]   (html [:a {:href url} url]))user=> (aslink “http://url1”)"<a href="http://url1">http://url1<...
map reduce(defn linkify [text]  (reduce #(.replace %1 %2 (aslink %2))     text (urls text)))               (fn [newText ur...
chaining(defn format-tweet [tweet]   1         2  [:li (:from_user tweet)    [:blockquote (-> tweet :text linkify)]]) Java...
chaining(defn format-tweet [tweet]   1         2 2  [:li (:from_user tweet)    [:blockquote (-> tweet :text linkify)]]) Ja...
chaining(defn format-tweets [json]  [:ul (->> json :content :results            (remove #(-> % :text urls nil?))          ...
chaining(defn format-tweets [json]            5  [:ul (->> json :content :results            (remove #(-> % :text urls nil...
ring server% lein ring server2011-04-16 21:18:54.965:INFO::Logging to STDERR via org.mortbay.log.StdErrLog2011-04-16 21:18...
src/twitturl/core.clj 1   (ns twitturl.core 2     (:use [ring.middleware.params]) 3     (:use [hiccup.core]) 4     (:requi...
Finding Clojure    https://github.com/kurtharriger/twitturl     Leiningen                Ring framework     DSLs          ...
Finding Clojure
Upcoming SlideShare
Loading in...5
×

Finding Clojure

1,849

Published on

Kurt Harriger's Ignite presentation to DOSUG on how to use Clojure to talk to web services.

Published in: Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,849
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Finding Clojure

  1. 1. Finding ClojureKurt Harriger @kurtharriger
  2. 2. The ChallengeTwitter search url filter
  3. 3. Project Folder% lein new twitturlCreated new project in: /Users/kurtharriger/code/twitturl├── README├── project.clj├── src│   └── twitturl│   └── core.clj└── test └── twitturl └── test └── core.clj % git init && git add -A && git commit -m “create project”
  4. 4. project.clj(defproject twitturl "1.0.0-SNAPSHOT" :description "Twitturl aggregator" :dependencies [[org.clojure/clojure "1.2.0"] [org.clojure/clojure-contrib "1.2.0"] [ring "0.3.7"] [clj-http "0.1.2"]] :dev-dependencies [[lein-ring "0.4.0"]] :ring {:handler twitturl.core/app})
  5. 5. Appleholics% brew install leiningen Non AppleholicsFind Leiningen for Clojure onhttps://github.com/technomancy/leiningen% lein self-install
  6. 6. S-Expressions Clojure: (defn fn [arg1 & more] arg1)defn is a macro used here with 3 parameters:function name, arguments, and body.Returns the function binding. Clojure: (println (fn value1 value2)) Java: System.out.println(fn(value1, value2));
  7. 7. S-Expressions Clojure: (defn fn [arg1 & more] arg1)defn is a macro used here with 3 parameters:function name, arguments, and body.Returns the function binding. Clojure: (println (fn value1 value2)) Java: System.out.println(fn(value1, value2));
  8. 8. ring framework(ns twitturl.core (:require [com.twinql.clojure.http :as http]) (:use [ring.middleware.params]) (:use [hiccup.core])) Import dependencies(defn handler [] nil) ;todo create handler(def app (-> handler wrap-params)) -> operator used apply multiple Entry point functions to handler
  9. 9. De-structuring(defn format-tweets [json] nil) ; todo(defn handler [{{q "q"} :params}] { :content-type "text/html" :body (html [:body (-> (search q) format-tweets)])})same as: Only need q(defn handler [request] (let [params (request :params) Local variable assignments q (params "q")] request and params {:content-type "text/html" unnecessary. :body (html [:body (-> (search q) format-tweets)])}))
  10. 10. The Search(def url "http://search.twitter.com/search.json") define readonly variable named url(defn search [query] (http/get url :query {:q query} :as :json)) returns result of com.twinql.clojure.http.get using parameter list 1) url 2) :query 3) {:q query } 4) :as 5) :json
  11. 11. Enter the repl% lein depsCopying 22 files to /Users/kurtharriger/code/twitturl/libCopying 17 files to /Users/kurtharriger/code/twitturl/lib/dev% lein replREPL started; server listening on localhost:24319.user=> (use ‘twitturl.core)niluser=> (search “clojure”){:code 200, :reason "OK", :content {:results [{:from_user "planetclojure", :text "Removing defined tests in Clojure REPL http://goo.gl/fb/qeUty #clojure #SO", ... }, ...] }}
  12. 12. The Handler(defn format-tweets [json] nil) ; todo(defn handler [{{q "q"} :params}] { :content-type "text/html" :body hiccup library function (html [:body (-> (search q) format-tweets)])}) same as (format-tweets (search q)) returns a map containing :content-type and :body
  13. 13. functions(defn aslink [url] (html [:a {:href url} url]))user=> (aslink “http://url1”)"<a href="http://url1">http://url1</a>"(def urls (partial re-seq #"http://S+"))same as:(defn urls [text] (re-seq #“http://S+” text))user=> (urls “blah blah http://url1 http://url2”)("http://url1" "http://url2")
  14. 14. map reduce(defn linkify [text] (reduce #(.replace %1 %2 (aslink %2)) text (urls text))) (fn [newText url] (.replace newText url (aslink url))String linkify(String text) { String newText = text; for(String url : getUrls(text)) { newText = newText.replace(url, asLink(url)); } return newText;}
  15. 15. chaining(defn format-tweet [tweet] 1 2 [:li (:from_user tweet) [:blockquote (-> tweet :text linkify)]]) Java: linkify(tweet.get(“text”))
  16. 16. chaining(defn format-tweet [tweet] 1 2 2 [:li (:from_user tweet) [:blockquote (-> tweet :text linkify)]]) Java: linkify(tweet.get(“text”)) 4 Java requires more(parentheses)?!
  17. 17. chaining(defn format-tweets [json] [:ul (->> json :content :results (remove #(-> % :text urls nil?)) (map format-tweet))])ArrayList<String> formatTweets(JSONObject json) { StringBuilder tweets = new StringBuilder(); tweets.append(“<ul>”); JSONObject content = json.getJSONObject(“content”); JSONArray results = json.getJSONArray(“results”); for(JSONObject tweet : results) { String[] urls = getUrls(tweet.getString(“text”)) if(urls != null && urls.length > 0) { tweets.append(“<li>” + formatTweet(tweet) “</li>”); } } tweets.append(“</ul>”); return tweets;}
  18. 18. chaining(defn format-tweets [json] 5 [:ul (->> json :content :results (remove #(-> % :text urls nil?)) (map format-tweet))])ArrayList<String> formatTweets(JSONObject json) { StringBuilder tweets = new StringBuilder(); tweets.append(“<ul>”); JSONObject content = json.getJSONObject(“content”); JSONArray results = json.getJSONArray(“results”); for(JSONObject tweet : results) { 12 String[] urls = getUrls(tweet.getString(“text”)) if(urls != null && urls.length > 0) { tweets.append(“<li>” + formatTweet(tweet) “</li>”); } } Java usually requires more(parentheses)?! tweets.append(“</ul>”); return tweets;}
  19. 19. ring server% lein ring server2011-04-16 21:18:54.965:INFO::Logging to STDERR via org.mortbay.log.StdErrLog2011-04-16 21:18:54.968:INFO::jetty-6.1.262011-04-16 21:18:54.998:INFO::Started SocketConnector@0.0.0.0:3000Started server on port 3000% lein ring warCreated /Users/kurtharriger/code/twitturl/twitturl-1.0.0-SNAPSHOT.warAmazon Elastic Beanstalk pluginhttps://github.com/weavejester/lein-beanstalk
  20. 20. src/twitturl/core.clj 1 (ns twitturl.core 2 (:use [ring.middleware.params]) 3 (:use [hiccup.core]) 4 (:require [com.twinql.clojure.http :as http])) 5 6 (def url "http://search.twitter.com/search.json") 7 8 (defn search [query] (http/get url :query {:q query} :as :json)) 9 (defn aslink [url] (html [:a {:href url} url]))1011 (def urls (partial re-seq #"http://S+"))1213 (defn linkify [text]14 (reduce #(.replace %1 %2 (aslink %2)) text (urls text)))1516 (defn format-tweet [tweet]17 [:li (:from_user tweet)18 [:blockquote (-> tweet :text linkify)]])1920 (defn format-tweets [json]21 [:ul (->> json :content :results22 (remove #(-> % :text urls nil?))23 (map format-tweet))])2425 (defn handler [{{q "q"} :params}]26 { :content-type "text/html"27 :body (html [:body (-> (search q) format-tweets)])})2829 (def app (-> handler wrap-params ))
  21. 21. Finding Clojure https://github.com/kurtharriger/twitturl Leiningen Ring framework DSLs Lists are awesome Less () than Java De-structuring Method chaining High-order functionsKurt Harriger @kurtharriger

×