finding clojure - amazon s3 · ├── readme ├── project.clj ├── src │ └──...

22
Finding Clojure Kurt Harriger @kurtharriger

Upload: others

Post on 01-Jul-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

Finding Clojure

Kurt Harriger @kurtharriger

Page 2: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

The Challenge

Twitter search url filter

Page 3: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

├── README├── project.clj├── src│   └── twitturl│   └── core.clj└── test └── twitturl └── test └── core.clj

Project Folder% lein new twitturlCreated new project in: /Users/kurtharriger/code/twitturl

% git init && git add -A && git commit -m “create project”

Page 4: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(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})

project.clj

Page 5: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

Appleholics% brew install leiningen

Non AppleholicsFind Leiningen for Clojure on

https://github.com/technomancy/leiningen

% lein self-install

Page 6: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

Clojure:(defn fn [arg1 & more] arg1)

Clojure: (println (fn value1 value2))

Java:System.out.println(fn(value1, value2));

S-Expressions

defn is a macro used here with 3 parameters: function name, arguments, and body. Returns the function binding.

Page 7: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

Clojure:(defn fn [arg1 & more] arg1)

Clojure: (println (fn value1 value2))

Java:System.out.println(fn(value1, value2));

S-Expressions

defn is a macro used here with 3 parameters: function name, arguments, and body. Returns the function binding.

Page 8: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(ns twitturl.core (:require [com.twinql.clojure.http :as http]) (:use [ring.middleware.params]) (:use [hiccup.core]))

(defn handler [] nil) ;todo create handler

(def app (-> handler wrap-params))

ring framework

Import dependencies

Entry point-> operator used apply multiple

functions to handler

Page 9: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(defn format-tweets [json] nil) ; todo

(defn handler [{{q "q"} :params}] { :content-type "text/html" :body (html [:body

(-> (search q) format-tweets)])})

same as:

(defn handler [request] (let [params (request :params) q (params "q")] {:content-type "text/html" :body (html [:body

(-> (search q) format-tweets)])}))

De-structuring

Local variable assignments request and params

unnecessary.

Only need q

Page 10: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(def url "http://search.twitter.com/search.json")

(defn search [query] (http/get url :query {:q query} :as :json))

The Search

returns result of com.twinql.clojure.http.get using parameter list1) url 2) :query 3) {:q query } 4) :as 5) :json

define readonly variable named url

Page 11: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

% lein deps Copying 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", ... }, ...] }}

Enter the repl

Page 12: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(defn format-tweets [json] nil) ; todo

(defn handler [{{q "q"} :params}] { :content-type "text/html" :body

(html [:body (-> (search q) format-tweets)])})

The Handler

returns a map containing :content-type and :body

hiccup library function

same as (format-tweets (search q))

Page 13: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(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")

functions

Page 14: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(defn linkify [text] (reduce #(.replace %1 %2 (aslink %2)) text (urls text)))

String linkify(String text) { String newText = text; for(String url : getUrls(text)) { newText = newText.replace(url, asLink(url)); } return newText;}

map reduce

(fn [newText url] (.replace newText url (aslink url))

Page 15: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(defn format-tweet [tweet] [:li (:from_user tweet) [:blockquote (-> tweet :text linkify)]])

chaining

Java:

linkify(tweet.get(“text”))

1 2

Page 16: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(defn format-tweet [tweet] [:li (:from_user tweet) [:blockquote (-> tweet :text linkify)]])

chaining

4

2

Java requires more(parentheses)?!

Java:

linkify(tweet.get(“text”))

1 2

Page 17: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(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;

}

chaining

Page 18: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

(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;

}

chaining5

12

Java usually requires more(parentheses)?!

Page 19: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

% lein ring server2011-04-16 21:18:54.965:INFO::Logging to STDERR via org.mortbay.log.StdErrLog

2011-04-16 21:18:54.968:INFO::jetty-6.1.26

2011-04-16 21:18:54.998:INFO::Started [email protected]:3000

Started server on port 3000

% lein ring warCreated /Users/kurtharriger/code/twitturl/twitturl-1.0.0-SNAPSHOT.war

Amazon Elastic Beanstalk pluginhttps://github.com/weavejester/lein-beanstalk

ring server

Page 20: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test
Page 21: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

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])) 10 11 (def urls (partial re-seq #"http://\S+")) 12 13 (defn linkify [text] 14 (reduce #(.replace %1 %2 (aslink %2)) text (urls text))) 15 16 (defn format-tweet [tweet] 17 [:li (:from_user tweet) 18 [:blockquote (-> tweet :text linkify)]]) 19 20 (defn format-tweets [json] 21 [:ul (->> json :content :results 22 (remove #(-> % :text urls nil?)) 23 (map format-tweet))]) 24 25 (defn handler [{{q "q"} :params}] 26 { :content-type "text/html" 27 :body (html [:body (-> (search q) format-tweets)])}) 28 29 (def app (-> handler wrap-params ))

src/twitturl/core.clj

Page 22: Finding Clojure - Amazon S3 · ├── README ├── project.clj ├── src │ └── twitturl │ └── core.clj └── test └── twitturl └── test

Finding Clojure

Kurt Harriger @kurtharriger

DSLs

High-order functions

Lists are awesome

Less () than Java

Method chaining

Leiningen Ring framework

https://github.com/kurtharriger/twitturl

De-structuring