• Save
Finding Clojure
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Finding Clojure

  • 2,142 views
Uploaded 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.

More in: Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,142
On Slideshare
2,132
From Embeds
10
Number of Embeds
3

Actions

Shares
Downloads
0
Comments
0
Likes
1

Embeds 10

https://www.linkedin.com 5
http://www.linkedin.com 3
http://paper.li 2

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