Your SlideShare is downloading. ×
0
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Finding Clojure
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Finding Clojure

1,821

Published on

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

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,821
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Finding ClojureKurt Harriger @kurtharriger
  • 2. The ChallengeTwitter search url filter
  • 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. 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. Appleholics% brew install leiningen Non AppleholicsFind Leiningen for Clojure onhttps://github.com/technomancy/leiningen% lein self-install
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. chaining(defn format-tweet [tweet] 1 2 [:li (:from_user tweet) [:blockquote (-> tweet :text linkify)]]) Java: linkify(tweet.get(“text”))
  • 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. 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. 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. 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. 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. 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

×