Clojureåå¼·æ¥è¨ï¼ãã®ï¼ï¼ Clojureã«ãããã·ã¼ã±ã³ã¹ã®ç¹å¾´ã¨Javaãªãã¸ã§ã¯ãã®æ±ã
ããã«ã¡ã¯ã
ãããããæ¸ç±ã説æçãªå
容ãå¢ãã¦ããã®ã§åã«ã¹ãæ¸ãã§ã¯ãªãã
ç解ãããã¨ãã¾ã¨ãã¦ããæ¹éãåãã¾ãã
1.é 延ã·ã¼ã±ã³ã¹ã¨ç¡éã·ã¼ã±ã³ã¹
Javaã«ãã£ã¦Clojureã«ãªãã·ã¼ã±ã³ã¹ã®ä¸çªã®ç¹å¾´ããã®é
延ã·ã¼ã±ã³ã¹ã¨ç¡éã·ã¼ã±ã³ã¹ã§ãã
é
延ã·ã¼ã±ã³ã¹ã¯ãã®åã®éãããåè¦ç´ ãå¿
è¦ã«ãªã£ãå ´åã«åãã¦è©ä¾¡ããããã·ã¼ã±ã³ã¹ã
ç¡éã·ã¼ã±ã³ã¹ã¯ãèªç¶æ°å
¨ã¦ãã®ãããªãçè«ä¸ç¡éã«å¤ãåå¨ããã·ã¼ã±ã³ã¹ã
é常ã®ããã°ã©ãã³ã°è¨èªã§ã¯ãç¡éã·ã¼ã±ã³ã¹ãã¨ããã®ã¯å
·ä½åãããªãã
çæããæç¹ã§ã¡ã¢ãªã溢ãã¦çµãããã§ãããããã
ãã ãClojureã§ã¯é
延ã·ã¼ã±ã³ã¹ã«ãã£ã¦
ãå¿
è¦ã«ãªã£ãæç¹ã§è©ä¾¡ããããã¦ã¼ã¶å´ã§å¿
è¦ãªåã ãåå¾ãããã¨ãããã¨ãå¯è½ãªããã
ç¡éã®å¤ãçæããã·ã¼ã±ã³ã¹ãè¨è¿°ãããã¨ãå¯è½ã¨ãªãã
ï¼ã¾ããå¤ãéå®ããé¢æ°ã¨ãã¢ã§ä½¿ç¨ããªãã¨æçµçã«ã¯æº¢ãããã§ããã
å½ç¶ãé
延ã·ã¼ã±ã³ã¹ã«ã¯å©ç¹ããããã§ããã
ä»ã®è¨èªã«æ
£ãã¦ãã人éã«ã¨ã£ã¦ã¯ä½¿ãã«ããã£ãããããã«ããç¹ãããã
ç¹ã«ãå¤é¨ã¸ã®å
¥åºåããä¼´ããããªå¯ä½ç¨ã¤ãã®å¦çã¨ã¯ç¸æ§ãé常ã«æªãã
ä½æ
ãªããäºããã¡ã¤ã«ãèªã¿è¾¼ãã§ããããã®ã«é
延è©ä¾¡ãããé¢ä¿ä¸ã
ã使ãã¨ãã«ãªã£ãã¿ã¤ãã³ã°ã§èªããã¨ããå½¢ã«ãªããããã¿ã¤ãã³ã°ã ããã¡ã¤ã«ï¼©ï¼¯ãçºçãããã¨ããã®ãåºæ¥ãªãããã
ã»ã»ã»ã¨ããããã§ãé
延ã§ãªãã·ã¼ã±ã³ã¹ã使ããããã§ãã
ãªã®ã§ãããæ£ç´éãããããã¾ããã
user=>(def print-range (for [index (range 10)] (do (println index)))) #'user/print-range ; ãã®æ®µéã§ã¯print-rangeã¯rangeã®ä¸èº«ãè©ä¾¡ãã¦ããªããããClojureã¯rangeã®é¨åãå®è¡ãã¦ããªãã user=> (doall print-range) 0 1 2 3 4 5 6 7 8 9 (0 1 2 3 4 5 6 7 8 9) ; é常ã«åããã«ããããæåã®10è¡ãprintã®çµæã§ãæå¾ã®ï¼è¡ãã·ã¼ã±ã³ã¹è©ä¾¡ user=> (def result (doall print-range)) #'user/result ; æ´ã«ããããããªããã¨ã«çµæãå¤æ°ã«ãã¤ã³ãããéã«ã¯printããããªãã user=> result (0 1 2 3 4 5 6 7 8 9) ; ãã¤ãdoallãããªãã§åä½ãå¤ããããä¸æã§ãã»ã»ã» user=> (def lazy (range 10)) #'user/lazy user=> (def imidi (doall (range 10))) #'user/imidi user=> lazy (0 1 2 3 4 5 6 7 8 9) user=> imidi (0 1 2 3 4 5 6 7 8 9) user=> (class lazy) clojure.lang.LazySeq user=> (class imidi) clojure.lang.LazySeq user=> (str lazy) "clojure.lang.LazySeq@9ebadac6" user=> (str imidi) "clojure.lang.LazySeq@9ebadac6"
çµå±é
延è©ä¾¡ã·ã¼ã±ã³ã¹ã«å¯¾ãã¦doallã使ç¨ãããã¨ã§å
·ä½çã«ã©ãããéãããããã¯åãããã
ã¨ãããããé
延è©ä¾¡ã«ãã£ã¦åé¡ãçºçããå ´åã«ä½¿ããä½ãç¾ç¶ã®ç解ã§ãããã¨ãªãã§ããããã»ã»ã»
2.Javaã®è¦ç´ ãã·ã¼ã±ã³ã¹ã¨ãã¦æ±ã
Javaã§ã³ã¬ã¯ã·ã§ã³çãªè¦ç´ ãå«ããã®ãClojureã®ã·ã¼ã±ã³ã¹ã«æ¸¡ãã¨
ã·ã¼ã±ã³ã¹ã¨ãã¦æ±ãããã
ããã¯æååããã¤ãå¤ã«ã¤ãã¦ããåæåãã¨ã«å解ããã·ã¼ã±ã³ã¹ãã¨ãã¦æ±ããããé©ç¨ç¯å²ãåºãã§ãã
user=> (seq "Hello Test") (\H \e \l \l \o \space \T \e \s \t) ; æååã渡ãã¨ã·ã¼ã±ã³ã¹åãããã¨ãã§ãã user=> (seq (.getBytes "Hello Test")) (72 101 108 108 111 32 84 101 115 116) user=> (first (.getBytes "Hello Test")) 72 user=> (rest (.getBytes "Hello Test")) (101 108 108 111 32 84 101 115 116)
ãã ãããã¾ã§ãããã¯ãå
ã®è¦ç´ ãåç
§ãã¦ä½ã£ãã¤ãã¥ã¼ã¿ãã«ãªã·ã¼ã±ã³ã¹ãã§ãããã¨ã«æ³¨æã
SystemPropertyãåå¾ãã¦ä½ã£ãã·ã¼ã±ã³ã¹ãconsã§ãã¼ã¸ãã¦ãã¼ã¸å¾ã®ã·ã¼ã±ã³ã¹ãåå¾ãã¦ãã
ãã®ã·ã¼ã±ã³ã¹ã®å
容ãå®éã®SystemPropertyã«åæ ããã¦ããããã§ã¯ãªãããã§ããã
ã¡ãªã¿ã«ãæååã«éã£ã¦ã¯ä¸è¨ã®è¨æ³ã§ã·ã¼ã±ã³ã¹ãæååã«æ»ããã¨ãå¯è½ã§ãã
â»ãªããã¹ã¼ãã¼Preè¨æ³ã§è¨è¿°ããã¨ä¸èº«ã表示ãããªããããé常ã®æååã¨ãã¦è¨è¿°ãã¦ãã¾ãã
user=> (rest "Hello Test")
(\e \l \l \o \space \T \e \s \t)
user=> (str (rest "Hello Test"))
"(\\e \\l \\l \\o \\space \\T \\e \\s \\t)"
user=> (apply str (rest "Hello Test"))
"ello Test"
ã¨è¨ãã¤ã¤ããããã·ã¼ã±ã³ã¹ã®åè¦ç´ ã«å¯¾ãã¦stré¢æ°ãé©ç¨ï¼applyï¼ãã¦ããã ãã§ã
ä½ãç¹æ®ãªè¨è¿°æ¹æ³ã¨ããããã§ã¯ãªãã§ãã
æ£è¦è¡¨ç¾ã®ã·ã¼ã±ã³ã¹ã¨ãã¦ã®æ±ã
Javaã§ã¯æ£è¦è¡¨ç¾ã§ãããããåã
ã®æååãåãã ãéã«ç¹°ãè¿ããããã³ã°ããããã
ã©ã¤ãã©ãªã使ãå¿
è¦ãããã¾ãããClojureã ã¨ããããããæååãããªãã·ã¼ã±ã³ã¹ããç´æ¥çæãããã¨ãã§ããã
user=> (re-seq #"\w+" "the quick brown fox")
("the" "quick" "brown" "fox")
user=> (first (re-seq #"\w+" "the quick brown fox"))
"the"
user=> (class (re-seq #"\w+" "the quick brown fox"))
clojure.lang.Cons
user=> (rest (re-seq #"\w+" "the quick brown fox"))
("quick" "brown" "fox")
user=> (sort (re-seq #"\w+" "the quick brown fox"))
("brown" "fox" "quick" "the")
user=> (take 3 (re-seq #"\w+" "the q||< uick brown fox"))
("the" "quick" "brown")
æ£è¦è¡¨ç¾ã®ãããã®çµæãã·ã¼ã±ã³ã¹åå¯è½ã¨ãªã£ããã¨ã§ã
ä»ã®ã·ã¼ã±ã³ã¹ã¨åãããã«ããããªãã®ãæ±ãããã¨ãªãã¾ããã
ã³ã¼ãã¯é常ã«ã³ã³ãã¯ãã«ã§ãããã§ãã
以å¾ããã¡ã¤ã«ã·ã¹ãã ãã¹ããªã¼ã ãXMLçãé£ç¶ããæ¦å¿µããã·ã¼ã±ã³ã¹ã¨ãã¦æ±ããããã§ãã
ãã¡ã¤ã«ã·ã¹ãã ã®ã·ã¼ã±ã³ã¹
ä¸è¨ã®ããã«ãã¡ã¤ã«ã®ä¸è¦§ãseqé¢æ°ã«æ¸¡ããã¨ã§åã ã®ãã¡ã¤ã«èªä½ãã·ã¼ã±ã³ã¹ã¨ãã¦æ±ããã
user=> (.listFiles (new File "."))
#
user=> (seq (.listFiles (new File ".")))
(#
user=> (map (fn [target] (.getName target)) (seq (.listFiles (new File "."))))
(".git" ".gitignore" "classes" "lib" "README.md" "src" "startRepl.bat")
; mapã®è¿ãå¤ã¯LazySeqã ããæ¢ã«è©ä¾¡ã®çµãã£ããªã¹ããåãåã£ãã·ã¼ã±ã³ã¹ã¯ArraySeqã¨ãªã£ã¦ããã
user=> (class (map (fn [target] (.getName target)) (.listFiles (new File "."))))
clojure.lang.LazySeq
user=> (class (seq (.listFiles (new File "."))))
clojure.lang.ArraySeq
å¾ã¯ãããã£ããã¡ã¤ã«ã·ã¹ãã å°ç¨ã®ã·ã¼ã±ã³ã¹é¢æ°ãåå¨ããã
user=> (doc file-seq)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
clojure.core/file-seq
([dir])
A tree seq on java.io.Files
user=> (count (file-seq (new File ".")))
142
ã§ããããã¯å½ç¶ã·ã¼ã±ã³ã¹ã§ãããããã·ã¼ã±ã³ã¹ã®ãã£ã«ã¿ãé©ç¨å¯è½ã»ã»ã»
ã¨ãªãããã§ãã
å½ç¶ãªãããã£ã«ã¿ï¼ãã¡ã¤ã«ã§ãããã¨ãåæã¨ããè¿°èªã«ãªãããã§ã¯ããã¾ããã
user=> (defn modified? [targetFile] (> (.lastModified targetFile) (- (System/currentTimeMillis) 6000000)))
#'user/modified?
user=> (filter modified? (file-seq (new File ".")))
(#
user=>
ãã®ããããæ½è±¡åãè¡ã£ããã¨ã«ãããç¹å®ã®è¦ç´ ãåæã¨ããã·ã¼ã±ã³ã¹è¿°èªããå¿
è¦ã«ãªãã¾ããã
ãã®ä¸ã§ãããã ãæè»ã«å®è¡ã§ããã®ã¯å¤§ããã§ããã
ã¨è¨ãã¤ã¤ãä»åã®ã±ã¼ã¹ã®å ´åç¶æ
ãèããªã代ããã«currentTimeMillisã¡ã½ããã大éå¼ã³åºããã¦ããããã
ãã®è¾ºãã®ãã©ã³ã¹ã¯ã©ããã§å¿
è¦ãªã®ããããã¾ããã
ã¹ããªã¼ã ã®ã·ã¼ã±ã³ã¹
ã¹ããªã¼ã ã»ã»ã»ã¨ãã£ã¦ããããããããããã«ããã¡ã¤ã«èªã¿è¾¼ã¿ã·ã¼ã±ã³ã¹ããç¨ãã確èªã«ãªãã¾ãã
line-seqé¢æ°ã使ç¨ããã¨ãã¡ã¤ã«ã®ä¸èº«ãã·ã¼ã±ã³ã¹ã¨ãã¦åå¾ã§ãã¾ããã
ãã¡ã¤ã«ã¯éãã£ã±ãªãã«ãªãã¾ãã
takeãã¤ãã¦ä¸é¨ããè©ä¾¡ããªãå ´åã§ããå
¨è©ä¾¡ããå ´åã§ãããã¯å¤ãããªãããã§ãã
user=> (use '[clojure.java.io :only (reader)])
nil
user=> (take 2 (line-seq (reader "src/functions.clj")))
("(defn hello \"Returns the form 'Hello, username.'\"" " [username]")
user=> (line-seq (reader "src/functions.clj"))
user=> (line-seq (reader "src/functions.clj"))
user=> (line-seq (reader "src/functions.clj"))
ã»ã»ã»çµæãä¸è¨ã®ããã«functions.cljãã¤ããã ãã¡ã¤ã«ãã³ãã«ãå¢ãã¦ãã¾ãããããã
ãããã£ãåé¡ã«ãªããªãããã«ããããã«ã¯with-openãã¯ãã§å²ã£ã¦ãããã¨ãå¿
è¦ãªããã§ãã
使ãå ´åã¯with-openãã¯ãå
ã§closeã¡ã½ãããä¿æãããã®ããã¤ã³ããã¦ä½¿ãã¾ãã
å¾ã¯with-openãã¯ãã§é
延è©ä¾¡ããããtake ã使ã£ãå ´åãã¹ããªã¼ã ãã¯ãã¼ãºããã¦ããæ¨ã®
ã¨ã©ã¼ãçºçããããããé
延è©ä¾¡ã«ã¤ãã¦å®æã§ãã¦ããæãã§ãã
ã§ãdoallã使ãã¨é
延è©ä¾¡ã«ãªããªãã®ã§æ£å¸¸ã«åä½ããã¨ã
ã»ã»ã»ãªãã§ããããã®ããããã³ã¼ãæ¸ãã¦ãã¦äºåã«æ¤ç¥ããã®ã¯ã¾ã ã¾ã é£ãããã§ã¯ããã¾ãã
user=> (with-open (take 2 (line-seq (reader "src/functions.clj"))))
IllegalArgumentException with-open requires a vector for its binding in user:29 clojure.core/with-open (core.clj:3450)
user=> (doc with-open)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
clojure.core/with-open
([bindings & body])
Macro
bindings => [name init ...]
Evaluates body in a try expression with names bound to the values
of the inits, and a finally clause that calls (.close name) on each
name in reverse order.
; é
延è©ä¾¡ããããããè©ä¾¡ã®ã¿ã¤ãã³ã°ã«ããã¦ã¯æ¢ã«ã¹ããªã¼ã ãã¯ãã¼ãºããã¦ãã
user=> (with-open [targetreader (reader "src/functions.clj")] (take 2 (line-seq targetreader)))
IOException Stream closed java.io.BufferedReader.ensureOpen (BufferedReader.java:115)
; doallé¢æ°ã使ã£ã¦å³æè©ä¾¡ããã¨é
延è©ä¾¡ã¨çµã¿åããã¦ãä¸èº«ãè¦ãã
user=> (with-open [targetreader (reader "src/functions.clj")] (take 2 (doall (line-seq targetreader))))
("(defn hello \"Returns the form 'Hello, username.'\"" " [username]")
å¾ã¯ãClojureã®ã³ã¼ãã®è¡æ°ãã«ã¦ã³ãããé¢æ°ãwith-openç¯ãç¨ãã¦ä¸è¨ã®ãããªæãã§ä½æã§ãã¾ããã
; 空è¡ã§ãªãè¡ãã©ãããå¤å®ããé¢æ°
(defn non-blank? [line] (if (re-find #"\S" line) true false))
; æå®ããããã¡ã¤ã«ãªãã¸ã§ã¯ããåãåãã空è¡ãé¤ããè¡ã®ã«ã¦ã³ããè¡ãé¢æ°
(defn clojure-realline [file] (with-open [targetreader (reader file)] (count (filter non-blank? (line-seq targetreader)))))
å¾ã¯Clojureã®ã½ã¼ã¹ãã©ãããå¤å®ãããã£ã«ã¿é¢æ°ã¨ãfile-seqãç¨ãã¦ãããã£ã¬ã¯ããªé
ä¸ã®Clojureã®ã½ã¼ã¹ã³ã¼ãã®è¡æ°ã
å¤å®ããé¢æ°ãä¸è¨ãããã§åºæ¥ã¾ããã
ã»ã»ã»ããããç¶æ
ããã¾ãèããªãã¦ããå¦çã§ããã°ããã ãã®ã³ã¼ãã§ããã辺ããé©ãã§ã¯ããã¾ãã
ã¨ã¯ãããï¼è¡ã§é¢æ°æ¸ãã¦ããé¢ä¿ä¸ãã¾ãã¡è¦ã«ããã¨ããã®ã¯ãããã§ããï¼æ±
; 対象ã®ãã¡ã¤ã«ãClojureã½ã¼ã¹ãã©ãããå¤å®ããé¢æ°
(defn clojure-source? [file] (.endsWith (.toString file) ".clj"))
; æå®ããããã¡ã¤ã«ãªãã¸ã§ã¯ãã®é
ä¸ãå帰çã«æ¢ç´¢ããClojureã½ã¼ã¹ã®è¡æ°ãã«ã¦ã³ãããé¢æ°
(defn clojure-loc-dir [basefile] (reduce + (for [file (file-seq basefile) :when (clojure-source? file)] (clojure-realline file)))
; Clojureèªä½ã®è¡æ°ã確èª
user=> (clojure-loc-dir (new java.io.File "clojure-master"))
26305
å°ããã®26305ã¨ããå¤ãã»ã¼ç¬éçã«åºã¾ãã
SSDã¨ã¯ãããæ°ç¾ãã¡ã¤ã«ã®è¡æ°ã«ã¦ã³ããã©ã°ãªãåºæ¥ãã®ã¯ããããã§ããã
ãã ãå
é¨ã§å並åå¦çããã¦ãããã¯ç¾ç¶ä¸æãªããããããã確èªãã¾ããããã
XMLã®ã·ã¼ã±ã³ã¹
åæ§ã«ãXMLãã·ã¼ã±ã³ã¹åãã¦æ±ããããã§ãã
user=> (use '[clojure.xml :only (parse)])
nil
user=> (parse (new java.io.File "clojure-master/pom.xml"))
{:tag :project, :attrs {:xmlns "http://maven.apache.org/POM/4.0.0", :xmlns:xsi "http://www.w3.org/2001/XMLSchema-instance", :xsi:schemaLocation "http://maven.apache.org/POM/4.0.0 ãçç¥
user=> (xml-seq (parse (new java.io.File "clojure-master/pom.xml")))
({:tag :project, :attrs {:xmlns "http://maven.apache.org/POM/4.0.0", :xmlns:xsi "http://www.w3.org/2001/XMLSchema-instance", ãçç¥
; pom.xmlä¸ã®:groupIdè¦ç´ ããå
容ãæ½åºããè¿ãã
user=> (for [x (xml-seq (parse (new java.io.File "clojure-master/pom.xml"))) :when (= (:tag x) :groupId)] (:content x))
(["org.clojure"] ["org.sonatype.oss"] ["org.codehaus.jsr166-mirror"] ["org.clojure"] ["org.clojure"] ["org.apache.maven.plugins"] ["org.codehaus.mojo"] ["org.apache.maven.plugins"] ["org.apache.maven.plugins"])