ページ

2024年12月2日月曜日

clojureのreplで実行したいコマンドはshellのパイプで渡せる


この記事はClojure Advent Calendar 2024の2日目の記事です。

プログラミング言語clojureには対話型の入力機能replがあります。
clojure-cliコマンドだとmainや関数の指定なしで実行した時に表示されるのがreplです。
nREPLを使うとportやhostを指定してreplを繋げます。

人が入力する前提で作られているからか事前に用意したコマンドをreplに渡す方法を見つけるのに時間を要しましたが、パイプで渡せば可能と分かりました。
echo "(+ 3 4)" | clj
Clojure 1.10.3
user=> 7
user=>
clojure-cliもnreplもパイプ渡しが想定されているのか、終了コマンドが無くても渡したコマンドを処理したらreplが閉じました。

たまに繰り返し動かしたい処理をnrepl clientを通して実施するshell scriptとして書いておくと、5秒ほどでnreplに繋がって処理を実行できて便利です。
#!/bin/bash

HOST=localhost
PORT=59595 # select port of server

echo "
(require '[clojure.tools.namespace.repl :refer [refresh]])
(refresh)
(require '[your.ns.to.use :as your-fn-to-call])
(your-fn-to-call)
" | clj -Sdeps '{:deps {nrepl/nrepl {:mvn/version "1.3.0"}}}' \
-M -m nrepl.cmdline \
--connect --host $HOST --port $PORT

上記のshell sciptはポート番号を59595に固定したnreplのserverの処理とrepl利用時の再読込便利関数を提供してくれるclojure.tools.namespaceを追加したprojectのnreplに対して実行する想定です。

clojure-cljのexec-fnやmainでの呼び出しだと自分の環境では実行までに30秒ほどかかり許容できない遅さでしたが、nreplにコマンドを渡す方式で5秒ほどの許容可能な待ち時間になりました。

おわりです。

実行環境
nREPL 1.3.0
Clojure 1.10.3
OpenJDK 64-Bit Server VM 18.0.1.1+2-6

参考
How to drop into a repl from within a Clojure command line application?
nREPL Server
nREPL Clients

0 件のコメント :

コメントを投稿