Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

Deno みたいに Scala を書く: Scala CLI 1.8.1 の using file ディレクティブの新機能

Scala CLI 1.8.1がしばらく前にリリースされていた。このリリースの主な変更は、using fileディレクティブで URL を展開する機能が利用できるようになったことだ。

github.com

この記事ではこの機能について紹介する。

Scala CLI とは

Scala CLI とはVirtusLab社によってメンテナンスされている、事実上標準の Scala 用 コマンドラインツールだ。

scala-cli.virtuslab.org

この記事でも何度も取り上げており、Scala によるスクリプティングやパッケージ作成などをスムーズに行うことができる非常に便利なツールだ。

blog.3qe.us

Scala CLIでは、.scala.scという拡張子でScalaコードを書くと、それを上から下へとそのまま実行してくれる:

// code.scala.sc
println("Hello, Scala CLI!")
% scala-cli code.scala.sc
(ファイルをそのまま渡すと scala-cli run ファイル したとみなされる)
Hello, Scala CLI!
%

ディレクティブとは

単一のScalaコードでできることは限られている。普通はビルドツールの助けを借りて、複数ファイルの結合や依存するライブラリの用意、コンパイラのバージョンの固定、コンパイルオプションの設定をやってもらっているのに、それができないからだ。

Scala CLI では、こうした「スクリプティングのために、ただコンパイルする以外にも必要なこと」をやってくれるための仕組みが用意されている。それがディレクティブ(directive)だ。

ディレクティブはファイルの先頭に//>という特殊なコメントの形式で書き込む:

//> using scala 3.7.1
//> using dep com.lihaoyi::os-lib:0.9.1
println("このスクリプトはかならずScala 3.7.1 コンパイラで処理される")
println(os.pwd) // ライブラリのメソッドを利用できる

特別な設定ファイルを用意せずにファイルのコメントで解決するという優れた仕組みによって、ファイル単体で非常に優れた移植性を発揮できるのが Scala CLI の優れた特長だ。

主なディレクティブとして以下のようなものがよく使われる:

  • using scala: Scala のバージョンを固定する
  • using dep: 外部ライブラリの利用を宣言する
    • Scala CLIが勝手にライブラリを用意してくれるので他にすることはない
  • using javaOpt: JAVA_OPTSを指定する
  • using option: Scala のコンパイラオプションを指定する
  • using platform: コンパイルターゲットを指定する
    • using platform jsとすれば Scala.js でコンパイルされる

利用可能なディレクティブの全ては、以下のページで一覧できる:

scala-cli.virtuslab.org

file ディレクティブ

そして、Scala CLI はusing fileというディレクティブを用意している。このディレクティブを利用すると、他のファイルをインクルードして実行できる:

//> using file another.scala

// ここでは another.scala に定義されたメソッドなどを呼べる

file ディレクティブに URL を指定する

さて、Scala CLI 1.8.1 では file ディレクティブにURLを指定する機能が追加された。つまり、これまではローカルなパスを指定していたところに、外部のURLを書くことで、自動的に Scala CLI にそのファイルをフェッチさせてコンパイルさせられるようになったということだ。

//> using scala 3.7.1
//> using file https://gist.github.com/windymelt/8814833b1e788874b3b9a7a1418abf1a/raw/f9812204a64785af4159c790293d2df09c805e54/library.scala

println(dev.capslock.gist.scalacli.Greeting.hello("Windymelt"))

このコードは以下の Gist を参照している:

gist.github.com

実行すると自動的に Gist のコードがフェッチされ、実行される:

% scala-cli run.scala.sc
Hello, Windymelt!

感想

URL を直接指定できるようになったことで、リリースが大変面倒な Maven Central を経由せずにアーティファクトを利用できるようになった。ただし、Maven Central にアップロードされた Scala のライブラリはあらかじめビルドされてバイトコードになっているのに対して、using fileを利用する方法は単に Scala コードをコンパイルするので、コンパイル分の手間がかかる(ビルド結果はキャッシュされる)ことに注意が必要だ。

また、今のところフェッチしてきたファイルの integrity を検証するための仕組みがないので、ドメインが奪取されるなどした場合に任意のコード実行が許されるという潜在的な危険性をはらんでいることに注意が必要だ。

developer.mozilla.org

個人的にも気になったのでGitHubに起票してみた。

github.com

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?