ハードウェアの気になるあれこれ

技術的に興味のあることを調べて書いてくブログ。主にハードウェアがネタ。

Scalaの勉強 - sbtを使ったコンパイルと実行

スポンサーリンク

引き続きScalaの学習をドワンゴScalaの研修資料を見ながらやっていく。
今日は"sbtでプログラムをコンパイル・実行する"。

sbtプロジェクトの作成

適当な名前でプロジェクト用のディレクトリを作って、その中にScalaのプログラムのファイルとビルド用のファイルbuild.sbtを置けばいい。
資料ではsandboxというディレクトリになっているのでそれに従って進める。

sandbox
├── HelloWorld.scala
└── build.sbt

記法も含めて慣れていくために、写経する。

object HelloWorld {
    def main(args: Array[String]): Unit = {
        println("Hello, World!!")
    }
}
  • build.sbt
scalaVersion := "2.12.6"

scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlint")

sbtプロジェクトの実行

上記の2つのファイルを作成したあと、sandboxディレクトリに移動し

$ sbt

と実行すると、勝手にbuild.sbtの解析が始まる。 最初、上記のscalacOptionsをscalaOptionsと勘違いしており、以下のように”そんなオプションは無い!”と怒られてしまった。

[info] Updated file /home/dnn-admin/workspace/hw/study/2000_chisel/sandbox/project/build.properties: set sbt.version to 1.2.1
[info] Loading settings for project global-plugins from idea.sbt ...
[info] Loading global plugins from /home/dnn-admin/.sbt/1.0/plugins
[info] Loading project definition from /home/dnn-admin/workspace/hw/study/2000_chisel/sandbox/project
[info] Updating ProjectRef(uri("file:/home/dnn-admin/workspace/hw/study/2000_chisel/sandbox/project/"), "sandbox-build")...
[info] Done updating.
/home/dnn-admin/workspace/hw/study/2000_chisel/sandbox/build.sbt:3: error: not found: value scalaOptions
scalaOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlint")
^
[error] Type error in expression
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? q

build.sbtに誤りがなければ以下のようにsbtのシェルが起動する。

[info] Loading settings for project global-plugins from idea.sbt ...
[info] Loading global plugins from /home/dnn-admin/.sbt/1.0/plugins
[info] Loading project definition from /home/dnn-admin/workspace/hw/study/2000_chisel/sandbox/project
[info] Loading settings for project sandbox from build.sbt ...
[info] Set current project to sandbox (in build file:/home/dnn-admin/workspace/hw/study/2000_chisel/sandbox/)
[info] sbt server started at local:///home/dnn-admin/.sbt/1.0/server/3f8de47fa7c5e96122b9/sock
sbt:sandbox> 

sbtシェルでrunを実行するとHellowWorld.scalaが実行される。

sbt:sandbox> run
[info] Updating ...
[info] Done updating.
[info] Compiling 1 Scala source to /home/dnn-admin/workspace/hw/study/2000_chisel/sandbox/target/scala-2.12/classes ...
[info] Done compiling.
[info] Packaging /home/dnn-admin/workspace/hw/study/2000_chisel/sandbox/target/scala-2.12/sandbox_2.12-0.1.0-SNAPSHOT.jar ...
[info] Done packaging.
[info] Running HelloWorld 
Hello, World!!
[success] Total time: 2 s, completed 2018/09/03 18:21:25
sbt:sandbox> 

runコマンドでは、その環境下におけるScalaプログラムからmainメソッドを持っているオブジェクトを探して実行をしてくれるとのこと。
C言語とかの統合開発環境で勝手にMakefile作ってくれるのに似てる感じだけど、調べてみるといろいろ多機能だわ、これは。。
以下のsbtのリファレンスにによく使われるコマンドが載っている。

sbt Reference Manual — 実行

こちらの例題でみる sbt の方には自動ビルドやテストの継続実行などのフローが一通り体験できるチュートリアルがあるので後ほどトライしてみることにして資料に戻ろう。 引き続き、User.scalaを作って実行していく。

class User(val name: String, val age: Int)

object User {
    def printUser(user: User) = println(user.name + " " + user.age)
}

後々出てくるんだろうけど、これがScalaのクラスの定義になるのか。
Userクラスを宣言して、nameageがメンバ変数(と呼ぶのか?)になって、printUserというメソッドを持つという感じか。
このUserクラスを定義したUser.scalaがあるディレクトリでsbt consoleを起動すると、以下のように作成したクラスが使用できる。

scala> val u = new User("dnn-developer", 13)
u: User = User@4a3557e0

scala> User.printUser(u)
dnn-developer 13

ちなみにディレクトリを変更すると、以下のように”そんなクラスは無い”とエラーになる。
この辺はCのインクルードパスとかpythonのモジュールのインポートとかと一緒で、カレントディレクトリは探索パスに加えられるということみたい。

scala> val u = new User("dnn-developer", 13)
<console>:11: error: not found: type User
       val u = new User("dnn-developer", 13)

scalaコマンドでの実行

sbtを使わない場合は直接scalaコマンドにファイルを入力することでも実行可能。

$ scala ./HelloWorld.scala
Hello, World!!

scalacコマンドに流すとコンパイルされてバイナリコード(HelloWorld$.classというテキストじゃないファイル)が生成されてるように見える。

$ scalac ./HelloWorld.scala

見えるんだけど、これ何で動くの??
このあたりの関係がまだ良く理解できてない。 一通り文法学んでから、広げて調べていくことにしよう。