Closed13

Babashkaで遊ぼう

kip2kip2

日常的にスクリプトでもClojureを使いたいので、Babashkaにキャッチアップする試み。

kip2kip2

Waht is Babashka?

Babashkaとは、通常 bash などを使用して実行することを Clojure で簡単に行うことができる、スクリプト実行環境、と言えると思います。使用例は、ビルドスクリプト、コマンドラインユーティリティ、小規模なWebアプリケーション、git hook、AWS Lambda functions などだそうです。リソースが少ない時や起動が高速であるべき時などに向いているようです。
Babashkaは、standalone natively-compiled binary です。つまり、OSはJVMを実行するのではなく、Babashkaバイナリを実行します。コンパイルされたBabashkaバイナリは多くのClojureの名前空間とライブラリを持っています。(Babashka book Built-in namespaces)
Clojureを知っている人にとって、一言で言ってしまうと『起動が早いClojureでシェルスクリプトが作れる』ってことでいいのではないでしょうか。

https://zenn.dev/shinseitaro/books/9270abff642f59/viewer/4dbdbd

つまり、JVMのオーバーヘッドを気にすることなく、スクリプトでClojureが使えるって感じ。

公式サイト
https://babashka.org/
ソース
https://github.com/babashka/babashka

kip2kip2

インストール

前になにかの折に入れてたので省略!

一応疎通確認。

$ bb --version
babashka v1.12.194
kip2kip2

Hello world

とりあえず動作確認で動かしてみる。

まずファイルを作成する。

touch hello.clj

これをエディターで開いて、以下のようにコマンドを記載する。

(println "Hello Babashka!")

あとはターミナルから実行すればOK

$ bb helo.clj
Hello Babashka!
kip2kip2

スクリプトを実行可能にする

#!/usr/bin/env bb

(println "Hello Babashka!")

実行権限を追加する。

chmod +x hello.clj

あとはシェルスクリプトファイルの様に実行すればいい。

$ ./helo.clj
Hello Babashka!
kip2kip2

ユーザの入力を受け付ける

とりあえず、スクリプトで基本の一つである、ユーザ入力受付をやってみよう。

(println "入力してください")
(def input (read-line))

(println "入力された文字列はこれです:" input)
$ bb a.clj
入力してください
123
入力された文字列はこれです: 123
kip2kip2

引数受付

引数の入力を表示する場合は以下のようになる。

(def args *command-line-args*)
(println "引数:" args)
$ bb a.clj "123" "2" "3"
引数: (123 2 3)
kip2kip2

四則演算

とりあえず簡単に四則演算を行う。


(println "最初の数を入力してください")
(def a (Integer/parseInt (read-line)))
(println "次の数を入力してください")
(def b (Integer/parseInt (read-line)))

(println "足し算 " (+ a b))
(println "引き算 " (- a b))
(println "掛け算 " (* a b))
(println "割り算 " (/ a b))
bb a.clj
最初の数を入力してください
10
次の数を入力してください
5
足し算  15
引き算  5
掛け算  50
割り算  2
kip2kip2

交通費計算プログラム

月の交通費を計算するスクリプトを書いてみよう。

(def basic-expense 300)
(def business-trip-expense 514)

(println "今月の出勤の日数を入力してください。")
(def workdays (Integer/parseInt (read-line)))

(println "出張の日数を入力してください。")
(def business-trip-days (Integer/parseInt (read-line)))

(defn calculate-transportation-expenses [days trip-days]
  (let [transportation-cost (* (* 2 basic-expense) days)
        work-trip-expenxes (* business-trip-expense trip-days)]
    (+ transportation-cost work-trip-expenxes)))

(println "今月の交通費の合計は以下になります。")
(println (calculate-transportation-expenses workdays business-trip-days))

ユーザの入力はread-lineで取得できる。
String型として取得されるようなので、Integer/parseIntを用いてInteger型に変換する必要がある。

以下はread-lineの型情報参考。

test.clj

(println (type (read-line)))
$ bb test.clj
3 4
java.lang.String

実際に動作させるところ。

$ bb calc.clj
今月の出勤の日数を入力してください。
17
出張の日数を入力してください。
3
今月の交通費の合計は以下になります。
12108
kip2kip2

ファイル操作

ファイルの基本的にな操作。

java.ioを使うようだ。

(require '[clojure.java.io :as io])

;; ファイルに書き出す。
(spit "example.txt" "Hello, Babashka!")

;; ファイルの内容を読み込む。
(let [content (slurp "example.txt")]
  (println "ファイルの内容:" content))

;; ディレクトリ内のファイルを一覧。
(doseq [file (.listFiles (java.io.File. "."))]
  (println (.getName file)))

kip2kip2

簡易的なcurlツール

引数でもらったURLでGETリクエストするだけの単純なツール。

(require '[babashka.curl :as curl])

(def fetch-pass (first *command-line-args*))

(let [response (curl/get fetch-pass {:as :json})]
  (println "Status:" (:status response))
  (println "Data:" (:body response)))

使い方は以下のようになる。

$ bb curl.clj "https://jsonplaceholder.typicode.com/todos/1"
Status: 200
Data: {
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

ダブルクォーテーションで囲わなくてもいける。

 bb curl.clj https://jsonplaceholder.typicode.com/todos/1
Status: 200
Data: {
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}
kip2kip2

削除前提のメモ

  • メール送信プログラムを書いてみる。
このスクラップは2025/02/01にクローズされました