Scala Advent Calendar 8日目の記事です。
Scalaでスクリプト書いてますか?僕は書いてません、でした、最近までは。
隣のクラスのPythonやGoはインタープリタやコンパイラをインストールしたらすぐに適当なスクリプト書き始められるというのに、Scalaときたらちょっとしたスクリプト書くのにもsbtなりのビルドシステムをセットアップして〜みたいなことしないといけない。
そんなあなたにはこれ!
Scala CLI は Scala をサクッと書くための CLI ツールで、これさえインストールすればsbtなどのビルドツールを使わなくてもすぐに一通りのプログラムを書くことができるようになります。
インストール方法とかはドキュメントを見てもらって、Scala CLI 使ってなにか書いてみましょう。
ここ最近の為替レートのチャートを表示するスクリプト書いてみる
最近は円安すごくて為替レート気になりますよね。ということでCLIからサクッと為替レート見れるスクリプトを書いてみます。(とりあえずEUR->JPYで)
為替レートの取得には Exchange Rates API を使って、ライブラリは以下のものを使います。
- sttp HTTP client
- ujson JSON parser
- ASCII-Data ascii chart を表示
できました。(secret に取得したAPIトークンを入れてね)
#!/usr/bin/env -S scala-cli shebang --quiet //> using lib "com.softwaremill.sttp.client3::core:3.8.3" //> using lib "com.mitchtalmadge:ascii-data:1.4.0" //> using lib "com.lihaoyi::ujson:2.0.0" import ujson._ import sttp.client3._ import com.mitchtalmadge.asciidata.graph.ASCIIGraph import java.time._ val secret = "xxx" val endDate = if (args.length > 1) LocalDate.parse(args(1)) else LocalDate.now() val startDate = endDate.minus(Period.ofDays(90)) val client = SimpleHttpClient() val response = client .send( basicRequest .header("apikey", secret) .get( uri"https://api.apilayer.com/exchangerates_data/timeseries?start_date=${startDate}&end_date=${endDate}&base=EUR&symbols=JPY" ) ) val responseBody = response.body.getOrElse(throw new Exception("Service not responding")) val data = ujson.read(responseBody) val values = data("rates").obj.toSeq.sortBy(_._1).map((_, value) => value("JPY").num) println(ASCIIGraph.fromSeries(values.toArray).plot())
これを script.sc
として保存して以下のコマンドで実行。
$ scala-cli script.sc # もしくは $ chmod +x script.sc $ ./script.sc
実行すると直近90日のEUR->JPYの為替レートが以下のような感じのascii chartで表示されます。
解説
using lib
なんちゃらって何?
//> using lib "com.softwaremill.sttp.client3::core:3.8.3"
using directive っていうやつ。//> using lib "org::name:version"
でそのスクリプトからライブラリをダウンロードして使えるようにしてくれる。(裏側ではcoursierを使ってダウンロードされてivyキャッシュに保存されるので、実行するたびにダウンロードされることはないよ)。
どのバージョンのScalaが使われてるの?
デフォルトだと最新(今だと3.2.0)。
$ scala-cli -S 2.13.10 script.sc
みたいな感じで Scala のバージョンを指定したり
//> using scala "2.13.10"
を sc
ファイルの頭につけて、using directive でバージョン指定もできる。
IDE サポートは?
あります!
Metals の場合は .sc
ファイルを開くと、scファイルが見つかりました、ScalaCLI script としてインポートしますか? みたいなのが出るのでハイを押すと普通にIDE機能を使った状態でスクリプトを書くことができるようになる。
ammonite とは何が違うの?
裏側では ammonite 使ってます(それにいろいろ便利機能をラップした感じ)。なので ammonite でできることはだいたいできるはず。
ammonite でできること。
なんで ./script.sc
で実行できるの?
shebang に #!/usr/bin/env -S scala-cli shebang
って書いてるから。
https://scala-cli.virtuslab.org/docs/guides/scripts#self-executable-scala-script
これで Scala でもシュシュッとスクリプト書けるぞ!!!
良いブログ
ちなみに
(ちなみに今後 scala
コマンドをこの scala-cli で置き換えるという SIP が提案され、最近 accept されました)。