引き続きScalaの学習をドワンゴのScalaの研修資料を見ながらやっていく。
今日は"sbtでプログラムをコンパイル・実行する"。
sbtプロジェクトの作成
適当な名前でプロジェクト用のディレクトリを作って、その中にScalaのプログラムのファイルとビルド用のファイルbuild.sbt
を置けばいい。
資料ではsandboxというディレクトリになっているのでそれに従って進める。
sandbox ├── HelloWorld.scala └── build.sbt
記法も含めて慣れていくために、写経する。
- HellowWorld.scala
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 の方には自動ビルドやテストの継続実行などのフローが一通り体験できるチュートリアルがあるので後ほどトライしてみることにして資料に戻ろう。 引き続き、User.scalaを作って実行していく。
- User.scala
class User(val name: String, val age: Int) object User { def printUser(user: User) = println(user.name + " " + user.age) }
後々出てくるんだろうけど、これがScalaのクラスの定義になるのか。
User
クラスを宣言して、name
とage
がメンバ変数(と呼ぶのか?)になって、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
見えるんだけど、これ何で動くの??
このあたりの関係がまだ良く理解できてない。
一通り文法学んでから、広げて調べていくことにしよう。