Scala入門 (0) -環境構築-

[Scala入門目次](http://qiita.com/ababup1192/items/289480485e7f1de18d9e) へ

Scalaは、柔軟な言語表現・安全性を実現するために、**コンパイルタイム**をある程度犠牲にしている言語です。しかし、学習時にコンパイルタイムが長いのは、ストレスが溜まりモチベーションの低下にも繋がります。ですが、安心してください、**適切なコンパイル・実行環境を整えればコンパイル時間を抑えながら学習ができます**。

# JDKのインストール

省略します。お好きなJDK(1.8)をお好きな方法で入れてください。*JAVA_HOME*の設定もお忘れなく。物ぐさな方は、IntelliJ IDEAを使えば、IDEAがJDKを持ってきてくれます。

# Scalaコンパイラ と REPL のインストール

[Scalaバイナリ](http://www.scala-lang.org/download/)を持ってくるか、ご自分の環境に合わせてパッケージマネージャ等を使って入れてください。

以下のように、実行してバージョンが返ってくれば無事インストール完了です

```
$ scala -version
Scala code runner version 2.12.0 -- Copyright 2002-2016, LAMP/EPFL and Lightbend, Inc.
$ scalac -version
Scala compiler version 2.12.0 -- Copyright 2002-2016, LAMP/EPFL and Lightbend, Inc.
```

# scalacコマンドを利用したコンパイル

*scalac*コマンドを利用して、コンパイル・実行する場合は、以下のようにします。しかし、この手法は**コンパイルの度にJVMが再起動されるためコンパイルタイムが長く**、あまり良くない実行方法です。

```
$ scalac Hello.scala
$ scala Hello
```

## REPLで簡単な文法・メソッド確認

**単純に文法を確認するだけの場合は、REPL(Read Eval Print Loop)を利用**しましょう。コンパイルタイムを挟むこと無く文法を実行・確認できます。

```
$ scala
Welcome to Scala 2.12.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.

scala> (1 to 100).filter(_ % 2 == 0).map(_ + 10).toList
res0: List[Int] = List(12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110)
```

*:paste*を使うと複数行に渡るコマンドも実行できます。

```
scala> :paste
// Entering paste mode (ctrl-D to finish)

class A(val x: Int) {
    def hoge: String = (x * 2).toString
}

// Exiting paste mode, now interpreting.

defined class A
```

# sbt or activator のインストール

複雑なプログラムを記述する場合には、Scalaをファイルに保存し、コンパイルする手順が必要不可欠です。ビルドツール[sbt](http://www.scala-sbt.org/0.13/docs/ja/Setup.html) (simple build tool) は、**対話環境を立ち上げている間、JVMを立ち上げ続け、さらに変更部分のみを部分コンパイル(インクリメンタルコンパイル)する**ため、**高速にコンパイルするために最適な方法**です。

sbtは、[Gradle](https://gradle.org)や[Bundler](http://bundler.io)と同じようなScalaで書かれたビルドツールです。CoCの要素も含んでいます。そのため、**予め決められたディレクトリ構成にする**必要があります。手動でディレクトリ構成を構築するのは面倒なため、sbtには、([gitter8](https://github.com/foundweekends/giter8))という**テンプレートディレクトリを生成するための仕組み**が備わっています。

```
// sbt new テンプレート(Gitリポジトリ)名
$ sbt new scala/scala-seed.g8
[info] Loading global plugins from /Users/abab/.sbt/0.13/plugins
[info] Set current project to desktop (in build file:/Users/abab/Desktop/)
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Minimum Scala build.

name [My Something Project]: [空エンター]

Template applied in ./my-something-project
```

生成されたディレクトリは、この様な構成になっています。中身については、その都度説明していきたいと思いますが、しばらくの間は*src*以下のコードのみに集中して書けば問題ありません。

```
$ cd my-something-project
$ tree
.
├── build.sbt
├── project
│   ├── Dependencies.scala
│   └── build.properties
└── src
    ├── main
    │   └── scala
    │       └── example
    │           └── Hello.scala
    └── test
        └── scala
            └── example
                └── HelloSpec.scala

8 directories, 5 files
```

sbtコマンドをプロジェクトのルートで実行すると、対話環境が立ち上がります。この対話環境を起ち上げる == JVMの起動と同義になるので、**連続してコンパイルする場合には、この対話環境を立ち上げ続けてください**。また、ライブラリを利用したい場合は、*build.sbt*からライブラリを追加すると良いでしょう。

```
$ sbt
> compile
> run // compileして実行
[info] Compiling 1 Scala source to /Users/abab/Desktop/my-something-project/target/scala-2.12/classes...
[info] Running example.Hello
hello
[success] Total time: 5 s, completed 2017/02/21 23:29:08
> exit
```

対話環境を立ち上げずにコンパイルや実行をする手段もあります。

```
$ sbt run
[info] Loading global plugins from /Users/abab/.sbt/0.13/plugins
[info] Loading project definition from /Users/abab/Desktop/my-something-project/project
[info] Set current project to Hello (in build file:/Users/abab/Desktop/my-something-project/)
[info] Running example.Hello
hello
[success] Total time: 1 s, completed 2017/02/21 23:35:26
```

もう一つの方法として、[activator](http://www.lightbend.com/activator/download)を利用することができます。**activatorは、sbtのリッチラッパー**です。豊富なsbtテンプレート、Webアプリとして編集・デバッグ環境なども提供されています。

*new*コマンドでは、テンプレート名を指定せずに対話的にテンプレートを選択することができます。

```
$ activator new

Fetching the latest list of templates...

Browse the list of templates: http://lightbend.com/activator/templates
Choose from these featured templates or enter a template name:
  1) minimal-akka-java-seed
  2) minimal-akka-scala-seed
  3) minimal-java
  4) minimal-scala
  5) play-java
  6) play-scala
(hit tab to see a list of all templates)
> 4
> Enter a name for your application (just press enter for 'minimal-scala')
>
There already is a project with name: minimal-scala. Either remove the existing project or create one with a unique name.
```

生成されたディレクトリは、この様な構成になっています。個人的には、binディレクトリに*activator*のラッパが用意されていたり、*.gitignore*が用意されていたりと、しっかりしたテンプレートのため評価が高いです。

```
$ cd minimal-scala
$ tree
.
├── LICENSE
├── bin
│   └── activator
├── build.sbt
├── libexec
│   └── activator-launch-1.3.12.jar
├── project
│   └── build.properties
└── src
    ├── main
    │   └── scala
    │       └── com
    │           └── example
    │               └── Hello.scala
    └── test
        └── scala
            └── HelloSpec.scala

10 directories, 7 files

$ ls -a
./          .gitignore  LICENSE     build.sbt   project/
../         .idea/      bin/        libexec/    src/
```

実行は、sbtを利用してもactivator・ラッパを利用しても構いません。お好きな方法でコンパイル・実行を行ってください。

```
$ sbt run
$ activator run
$ bin/activator run
```

# エディタ・IDE

好みのものをお使いください。筆者の場合は、状況に応じて使い分けているので、参考程度にどうぞ。

- 軽量エディタ(vim, emacs?) 
- 中量エディタ(VSCode, Atom)
- IDE([IntelliJ IDEA](https://www.jetbrains.com/idea/), Scala IDE for Eclipse, Eclipse)

スペックが高いPCをお使いの方は、やはりIntelliJ IDEAをオススメします。補完機能やリファクタリング機能の質が段違いです。より良い書き方がある場合は、その書き方を提供し書き換えてくれたりするので、学習の効率が上昇すること間違い無しです。

IDEAのプロジェクト作成機能からsbtテンプレートを生成することもできますが、**Scalaやsbtのバージョンアップに追従していないケースがあるため推奨しません**。*sbt new*や*activator new*でプロジェクトを作成し、それをIDEAが開く形の方が安定するでしょう。コンパイル・実行もsbt対話環境から行ったほうが良いと思われます。


# まとめ

## 文法等を確認したい

scala(REPL)コマンドを使う。

## 複雑なプログラムやライブラリを利用したプログラムを書きたい

sbt or activator を利用する。

## プログラムの編集は何を使うか

状況に応じて、お好きなエディタを使う。スペックに問題が無ければ、IntelliJ IDEAを利用する。