はじめに
ClojureもYAMLもはじめての人向けです。
MacにClojureの環境を作りつつ、実際にYAMLをパースしながら基本的な構文を学びたくてまとめました。
Clojureのインストール
事前にHomebrewとJava8をインストールしておく必要があります。
Clojureのインストールは下記のコマンド一発です.
$ brew install leiningen
ターミナルでlein repl
を実行してプロンプトが起動すればインストール完了。
あとで使うので空のプロジェクトを作っておきます。
$ lein new yaml-test
<参考> Clojure環境を導入(mac)
https://qiita.com/FumiIwase/items/228a9c8dfdfbcde02d92
Visual Studio Codeのインストール
ここ (https://qiita.com/akiko-pusu/items/185f4fd8484ecd3b3243) とか、
ここ (https://www.karelie.net/install-vscode-mac/) を見ながらインストールしました。
Clojure開発環境のセットアップ
VSCodeでClojureアプリを開発するための環境をセットアップします。
まずは、Calvaをインストール
https://marketplace.visualstudio.com/items?itemName=cospaia.clojure4vscode
から[install]をクリック。
さらにVSCodeを開いて[install]をクリック。
簡単でした。
VSCodeのコマンドラインからreplを起動します。
$ lein repl
nREPL server started on port 50584 on host 127.0.0.1 - nrepl://127.0.0.1:50584
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_192-b12
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=>
起動したら、Ctrl+Alt+V C
で接続します。
replのポートが入っているのでそのまま[Return]でOK。
Ctrl+Alt+V C
で、もしコマンドが無いというエラーが出てきたら、Clojureのプロジェクトがちゃんとロードできていないみたいです。下記のようにVSCodeを開き直したらうまくいきました。
$ code project.clj .
左下にこんなのが出てたら成功です。
試しに下記のようなコードを追加して
(+ 1 3 )
コードを選択した状態でctrl+alt+v e
を押すと下記のようになります。
ちなみに、ファイルをセーブしないと出ませんでした(ちょっとはまりました)
<参考>VSCodeの拡張:CalvaでClojureの開発環境を整える
https://qiita.com/frost_star/items/4475acaeff84badbf3f7
なお、VSCodeのClojure開発環境をググるとclojureVSCodeがヒットしたのでこれも試してみましたが、下記のエラーが出るのであきらめました。もしかしたら、VSCode開き直しで動いたのかも。
Clojure Development with Visual Studio Code
https://spin.atomicobject.com/2017/06/22/clojure-development-with-visual-studio-code/
clojureVSCode
https://marketplace.visualstudio.com/items?itemName=avli.clojure
clj-yamlの導入
いよいよYAML Parserを使ってみます。
clj-yamlはMaven artifactとして使えるので、まずはproject.cljに依存ライブラリとして追加します。[circleci/clj-yaml "0.5.6"]
の箇所です。
ついでに最終行の:main yaml-test.core/-main
も追加しておきました。
(defproject yaml-test "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.8.0"]
[circleci/clj-yaml "0.5.6"]]
:repl {:plugins [[cider/cider-nrepl "0.18.0"]]
:dependencies [[nrepl "0.4.5"]]}
:main yaml-test.core/-main)
ファイルを保存したあとターミナルからlein deps
を実行しておきます。
$ lein deps
次にmain関数を作成します。:require
でclj-yaml.coreをyaml
で参照できるようにして、yaml/generate-string
でYAMLフォーマットの文字列を生成してみます。
(ns yaml-test.core
(:require [clj-yaml.core :as yaml] ))
(defn -main []
(println
(yaml/generate-string
[{:name "John Smith", :age 33}
{:name "Mary Smith", :age 27}])
)
)
lein run
で下記のように出力されたら成功です。
$ lein run
- {name: John Smith, age: 33}
- {name: Mary Smith, age: 27}
次は逆にYAMLをClojureアプリに取り込んでみます。
(ns yaml-test.core
(:require [clj-yaml.core :as yaml] ))
(defn -main []
(println
(yaml/parse-string "
- {name: John Smith, age: 33}
- name: Mary Smith
age: 27
")
)
)
実行します。
$ lein run
(#ordered/map ([:name John Smith] [:age 33]) #ordered/map ([:name Mary Smith] [:age 27]))
YAMLの動作確認
いろいろなYAMLをパースしてみました。
(ns yaml-test.core
(:require [clj-yaml.core :as yaml] ))
(defn -main []
(print "---\n【配列】\n")
(println (pr-str (yaml/parse-string "
- aaa
- bbb
- ccc
")))
(print "---\n【ハッシュ】\n")
(println (pr-str (yaml/parse-string "
A: aaa
B: bbb
C: ccc
")))
(print "---\n【ハッシュのネスト】\n")
(println (pr-str (yaml/parse-string "
A: aaa
B:
B1: bbb1
B1: bbb2
C: ccc
")))
(print "---\n【フロースタイル】\n")
(println (pr-str (yaml/parse-string "
{ A: aaa, B: bbb, C: ccc }
")))
(print "---\n【コメント】\n")
(println (pr-str (yaml/parse-string "
# コメント行
A: aaa
B: bbb
C: ccc
")))
(print "---\n【複数行の文字列】\n")
(println (pr-str (yaml/parse-string "
text: |-
aaa
bbb
ccc
")))
(print "---\n【アンカーとエイリアス】\n")
(println (pr-str (yaml/parse-string "
- &mark foo
- bar
- *mark
- *mark
")))
(print "---\n【ハッシュのマージ】\n")
(println (pr-str (yaml/parse-string "
base: &base
A: aaa
B: bbb
Sample1:
<<: *base
C: ccc1
Sample2:
<<: *base
C: ccc2
")))
)
結果はこんな感じ
$lein run
---
【配列】
("aaa" "bbb" "ccc")
---
【ハッシュ】
#ordered/map ([:A "aaa"] [:B "bbb"] [:C "ccc"])
---
【ハッシュのネスト】
#ordered/map ([:A "aaa"] [:B #ordered/map ([:B1 "bbb2"])] [:C "ccc"])
---
【フロースタイル】
#ordered/map ([:A "aaa"] [:B "bbb"] [:C "ccc"])
---
【コメント】
#ordered/map ([:A "aaa"] [:B "bbb"] [:C "ccc"])
---
【複数行の文字列】
#ordered/map ([:text "aaa\nbbb\nccc"])
---
【アンカーとエイリアス】
("foo" "bar" "foo" "foo")
---
【ハッシュのマージ】
#ordered/map ([:base #ordered/map ([:A "aaa"] [:B "bbb"])] [:Sample1 #ordered/map ([:A "aaa"] [:B "bbb"] [:C "ccc1"])] [:Sample2 #ordered/map ([:A "aaa"] [:B "bbb"] [:C "ccc2"])])
アンカーとエイリアス、ハッシュのマージなんかはYAMLで設定ファイルを書くときに便利そうです。
<参考>
プログラマーのための YAML 入門 (初級編)
https://magazine.rubyist.net/articles/0009/0009-YAML.html
YAML 基本記法まとめ
https://qiita.com/tfrcm/items/5f8e4c5795ce41b214d1
おわりに
YAMLの勉強のついでにClojureも勉強しようと思ってやってみましたが、Clojure面白いですね。
replを使えば簡単に実行できるし、関数型プログラミングを学ぶのに良い気がしてきました。
今度はClojureでWebアプリを作ってみたいです。