🥰

Scala CLI ではじめる Scala スクリプティング

2022/04/20に公開

簡単なツールや業務効率化のためのスクリプトを書く際に Scala を使ってみませんか(^ω^)?

Python や Ruby などの動的型付け言語と比べて、次のようなメリットがあります.

  1. 静的型付けなのでコンパイル時にエラーがわかる.
  2. エディタやLSP(metals)など、普段のプロジェクトで使っている開発ツールがフルに使える
  3. ライブラリのインポート、言語のバージョンやコンパイラオプションの指定がひとつの .scala ファイルで完結する. nodenv, rbenv や pyenv のようなツールが不要😊
  4. 必要に応じて JavaScript や ネイティブコードにコンパイルできる
  5. もちろん Scala 3 にも対応しているので、インデント記法でスッキリコードを書ける❤

はじめかた

Install

For Linux and MacOS

curl -fL https://github.com/Virtuslab/scala-cli/releases/latest/download/scala-cli-x86_64-pc-linux.gz | gzip -d > scala-cli
chmod +x scala-cli
sudo mv scala-cli /usr/local/bin/scala-cli
scala-cli --version
0.1.0

Docker イメージ

死んでもローカル環境を汚したくないマンのために Docker を使ったケースも紹介します.

tree
// => └── A.scala
A.scala
@main def f() = println("hello, world!")
docker run --rm -it  --workdir /app  --volume `pwd`:/app  virtuslab/scala-cli run A.scala
// => hello, world!

github actions も用意されています😊うれしいですね.

action.yaml
    steps: 
      - uses: coursier/cache-action@v6
      - uses: VirtusLab/scala-cli-setup@main

その他のインストール方法については Scala CLI のインストールの章 をみてください.

基本

Scala ファイルの実行

*.scala ファイルと *.sc ファイルの両方をサポートしています. *.sc ファイルは ammonite と呼ばれる Scala のツールに対応したファイル形式です.

Scala CLIを使うとき、どちらも次のようにトップレベルに関数を定義できます.

example.scala
@main def program = println("hello, Scala CLI!")
example.sc
println("hello, Scala CLI!")

*.scala ファイル、*.sc ファイルは次のように実行できます.

scala-cli example.scala
scala-cli example.sc
hello, Scala CLI!

コマンドライン引数をとる関数は以下のように args を受け取る関数として定義します.

WithArgs.scala
@main def f(args: String *) = println(args.mkString)

コマンドの引数は次のように渡せます.

scala-cli WithArgs.scala -- hello world!

*.sc ファイルを使う場合は、デフォルトで args 変数が定義されています.

WithArgs.sc
println(args.mkString)
scala-cli WithArgs.sc -- hello world!

インタラクティブにコードを実行したい場合は scala-cli console コマンドで REPL に入れます.

Editor のセットアップ

以下のようにディレクトリを指定して IDE サポートを有効にすることができます.

scala-cli setup-ide .

次のようなディレクトリ構成の場合、<current dir>scala-cli setup-ide . を実行しましょう. 個別のファイルに対しても scala-cli setup-ide A.scala を実行できますが非推奨です.

$tree
<current dir>
├── A.scala
└── B.scala

0 directories, 2 files

環境の設定

*.scala ファイルの冒頭に使える using directives コメント、または Scala CLI へのオプションからプログラムの環境を編集できます.

Scala バージョン

A.scala
//> using scala "3.1.2"

コンパイラオプション

A.scala
//> using options "-Xasync"

Scala.js

A.scala
//> using platform "scala-js"

または

scala-cli A.scala --js

Scala.js は package コマンドで node で実行可能な *.js にコンパイルできます.

例:

A.scala
//> using platform "scala-js"

@main def f() = println("hello, world!")
scala-cli package A.scala
node ./A.js
// => hello, world!

参考: Scala CLI の Scala.js の章

ライブラリのインポート

Using directives を利用する場合

//> using lib "org.typelevel::cats:2.7.0"

注意点

Scala.js や Scala Native の依存をフェッチする場合は、バージョン番号の前に :: が必要です.

-//> using lib "org.typelevel::cats:2.8.0"
+//> using lib "org.typelevel::cats::2.8.0"

https://youforgotapercentagesignoracolon.com/

$ivy, $deps シンタックスを使う場合

import $ivy.`org.typelevel::cats:2.7.0`
import cats._

参考

さいごに

さあ、きみも Scala CLI を使って快適なスクリプティングをしよう(^ω^)

Discussion