最近仕事でちょっとしたスクリプト(ほとんどがファイル操作&ファイル名編集に正規表現を少し使う程度)を書く機会が何度かあり、そういった「ちょっとした機会」にでも Clojure を使えたらなぁ、と思っていました。1
そういった用途に、最近だと babashka 、少し前からだと lumo 、planck 、等が候補になるかと思います。各々特長がありますが、ちょっとマイナー(?失礼)な planck について気に入った点、そうでなかった点等々調べてみたことを書いてみようと思います。
Planck とは
実行エンジンに JavaScriptCore (Safari / WebKit2 に使われてるやつ) を使った、ClojureScript の処理系、です。普通に REPL を起動してインタラクティブに操作することもできますし、ClojureScript で記述したスクリプトを食わせてバッチ的に処理させることもできます。まあ普通に shell みたいなもの、ですね。
JVM 上の Clojure と対比して、「起動がやたら速い」ので、ちょっとしたスクリプト記述にはちょうど良いですね。
使い方(超ざっくり)
planck の使い方について、以下にざっくりと示します。
インストール
公式には macOS(homebrew)、Ubuntu(apt-get)のインストール手順が記載されていますが、linux であれば条件があえばビルドできるかもしれません。
REPL
planck
または plk
コマンドで REPL に入ります。
bash$ plk
ClojureScript 1.10.520
cljs.user>
TAB キーによる completion もある程度効くようです。ただ、planck 自体は nREPL をサポートしていないので、CIDER や vim-iced といった強力な IDE が使えるわけではありません。それでも、emacs から使う分には、inf-clojure 経由で REPL を使うことができます(設定についてはGUIDE参照)。
ワンライナー
-e
に続けて式を書けば評価してくれます。
bash$ plk -e ‘(range 10)’
(0 1 2 3 4 5 6 7 8 9)
bash$
スクリプト
(println “Hello World!”)
bash$ plk hello.cljs
Hello World!
bash$
あるいは、shebang に書いておいて実行
#!/usr/bin/env plk
(println “Hello World!”)
bash$ chmod +x hello.cljs
bash$ ./hello.cljs
Hello World!
bash$
ここまでは簡単ですよね。
使える機能(API)
Clojure/JVM の場合だと単体でJVM標準のAPIが使えますので、特に外部ライブラリに頼らずともファイル操作程度のことはできますし、JVM 由来の clojure.java.io
あたりを使えばより簡単にプログラミングできます。
一方 planck の場合は、shell scripting に必要な機能、REPL実装に必要な機能、は、名前空間 planck.*
に用意されています。
- planck.core
- planck.repl
- planck.io
- planck.shell
- planck.http
- planck.environ
細かな説明は割愛しますが、例えば (require ‘[planck.io :as io])
としておけば、 (io/as-file “filename”)
のように、Clojure/JVM の clojure.java.io
っぽい書き方ができます2。
外部ライブラリとの連携
JavaScript ベースなので npm でインストールできるライブラリを使いたいところですが、planck は JavaScriptCore ベースなので残念ながら使えません。とはいえ、何も手がないわけではなく、 cljsjs に登録されているものであれば、(ものによっては)使えるようです。
(例1) moment
bash$ plk -Sdeps ‘{:deps {cljsjs/moment {:mvn/version “2.24.0-0”}}}’
ClojureScript 1.10.520
cljs.user=> (require ‘moment)
nil
cljs.user=> (.format (moment) “YYYY-MM-DD HH:mm:ss,SSS”)
“2019-12-15 22:55:29,627”
cljs.user=>
(例2) AWS JavaScript SDK 3
bash$ plk -Sdeps ‘{:deps {cljsjs/aws-sdk-js {:mvn/version “2.421.0-0”}}}’
cljsjs.user=> (require ‘cljsjs.aws-sdk-js)
cljsjs.user=> (def s3 (AWS.S3.))
#’cljsjs.user/s3
cljsjs.user=>
所感
自分でもまだ planck でスクリプトをがっつり書いたわけではありませんが、Clojure のプログラミング言語としての使いやすさはとても魅力的なので、仕事の傍らででも使えればなぁ、とは思います。あと、気になった点について、以下にまとめておきます。
- lumo は nodejs ベースなので、npm 由来のパッケージを使える点は優位。
- lumo は nodejs ベースなので、Windows でも動く(一応動いた)。JavaScriptCore ベースの planck は、今のところ Windows 環境で動いている実績はなさそう(msys2等含む)。
- planck.io のようなビルトインがあるのは有り難い。JavaScript 的な「何でも非同期」なAPI ではなく、clojure.java.io と同じ感覚で使える、というのは planck の良いところだと思う。
- planck / lumo はどちらも起動が速いのだが、babashka にはやはり負けてしまう(GraalVM native image なのでそりゃそうだ、としかいいようがない)。
- ただし、babashka と違い、lumo / planck は、cljsjs 由来のライブラリへの依存を足してやることでスクリプト基盤そのものを拡張することができる点は優位かも。
- closh ってやつもあるが...今回は未調査。
以上です。