SlideShare ist ein Scribd-Unternehmen logo
1 von 104
未経験者のためのScala
株式会社イプロス 本多陽平
後半パート

Scalaの真髄に少しだけ触れる

2

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
自己紹介

• 本多陽平
• 2012年2月イプロス入社
• Java歴1年半→Scala歴半年
• 現在は広告系サービスの開発を担当
• 去年登山を始めました
• サッカーを観たり、梅干しをつけたり、温泉に行ったり、
が趣味
3

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
後半パートについて

後半パートでは、Scalaの
• オブジェクト指向要素
• 関数プログラミング要素
の両側面に簡単に触れるとともに、
SBTを使ったビルドについても触れます。

4

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
アジェンダ

1. Scalaでオブジェクト指向
1. クラス
2. トレイト

ハンズオン

2. Scalaで関数プログラミング
1. 高階関数

ハンズオン

3. SBTによるビルド
1. コンパイル
2. 実行
3. パッケージング

ハンズオン
ハンズオン
ハンズオン
5

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
前置き

Scalaの言語仕様を網羅的に説明して
いるわけではないので、ご了承下さい

6

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
サンプルコードについて

後半パートで使用するサンプルコードは以下
にアップロードしてあります。
イプロス開発ブログ
http://ipros-creators.tumblr.com/
※「イプロス 開発」で検索

7

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
オブジェクト指向要素編

Scalaで
オブジェクト指向

8

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス

Scalaは関数型言語であり、
オブジェクト指向言語でもあるので、
クラスを使えます

9

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

クラス定義

C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
| this("Unknown") } }
defined class Mountain

10

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ > 基本コンストラクタ

インスタンスが生成される度に呼ばれます

C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
| this("Unknown") } }
defined class Mountain

11

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ > クラスパラメータ

クラスパラメータは基本コンストラクタのパラメータとなります
C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
| this("Unknown") } }
defined class Mountain

12

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ > 補助コンストラクタ

thisキーワードをつけると、補助コンストラクタとなります
C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
※必ず初めに基本コンストラクタを
呼ぶ必要がある
| this("Unknown") } }
defined class Mountain

13

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

基本コンストラクタでインスタンス生成

C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
| this("Unknown") } }
defined class Mountain
scala> val fuji = new Mountain("Fuji")
fuji: Mountain = Mountain@23e9436c

14

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

名前は?

C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
| this("Unknown") } }
defined class Mountain
scala> val fuji = new Mountain("Fuji")
fuji: Mountain = Mountain@23e9436c
scala> fuji.

tabキーで補完

15

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

名前は?

C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
| this("Unknown") } }
defined class Mountain
scala> val fuji = new Mountain("Fuji")
fuji: Mountain = Mountain@23e9436c
scala> fuji.
asInstanceOf isInstanceOf printName

toString

↑可視性はデフォルトでPublic

16

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

名前は?

C-1

scala> fuji.
asInstanceOf isInstanceOf printName

toString

scala > fuji.printName
res0: String = Mt. Fuj

17

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

補助コンストラクタでインスタンス生成

C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
| this("Unknown") } }
defined class Mountain
scala> val nanashi = new Mountain()
nanashi: Mountain = Mountain@233a4b09

18

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

名前のない山ができました

C-1

scala> class Mountain (name: String) {
| val printName = "Mt. " + name
| def this() = {
| this("Unknown") } }
defined class Mountain
scala> val nanashi = new Mountain()
nanashi: Mountain = Mountain@233a4b09
scala> nanashi.printName
res0: String = Mt. Unknown

19

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

クラスパラメータがフィールドにありません

scala> fuji.
asInstanceOf isInstanceOf printName

20

C-1

toString

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

valをつけて定義するとフィールドになります

C-2

scala> class Mountain (val name: String)
defined class Mountain

21

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

nameにアクセスできました

C-2

scala> class Mountain (val name: String)
defined class Mountain
scala> val fuji = new Mountain("Fuji")
fuji: Mountain = Mountain@55a4221f
scala> fuji.
asInstanceOf isInstanceOf name

toString

scala> fuji.name
res1: String = Fuji

22

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > コンストラクタ

ここまでのまとめ

1. 基本コンストラクタ
class Mountain { val name = "Fuji" }

1. 補助コンストラクタ
class Mountain (val name: String) {
def this() = { this("Unknown") }}

1. クラスパラメータ
1.

フィールド指定なし

class Mountain (name: String)
1.

フィールド指定あり

class Mountain (val name: String)

23

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > メソッド

メソッド

24

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > メソッド

メソッド定義は簡単で、関数定義と同じです

C-3

scala> class Mountain (val name: String) {
| def erupt = { println("erupted!") }}
defined class Mountain

※呼び方(ということが多いです)
関数単体 = 関数
クラス内の関数 = メソッド

25

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > メソッド

呼び出し

C-3

scala> class Mountain (val name: String) {
| def erupt = { println("erupted!") }}
defined class Mountain
scala> val vesuvius = new Mountain("Vesuvius")
vesuvius: Mountain = Mountain@6f9c2c4
scala> vesuvius.erupt
erupted!

26

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > ハンズオン

噴火する度に標高が下がる山
を作ってみましょう

27

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > ハンズオン > コーディング例

こんな感じ

scala> class Mountain (val name: String, var alt: Int) {
| def erupt = {
| alt -= 100
| println("erupted! alt = " + alt) }}
defined class Mountain

28

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
クラス > ハンズオン > コーディング例 > 動作確認

動かしてみましょう

scala> class Mountain (val name: String, var alt: Int) {
| def erupt = {
| alt -= 100
| println("erupted! alt = " + alt) }}
defined class Mountain

scala> val vesuvius = new Mountain("Vesuvius", 1281)
vesuvius: Mountain = Mountain@4e3ecc02
scala> vesuvius.erupt
erupted! alt = 1181

← 下がってる

scala> vesuvius.erupt
erupted! alt = 1081

← 下がってる
29

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト

実装の定義も可能なJavaのインターフェース
という感じです

30

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト

traitキーワードをつけて定義します

T-1

scala> trait Mountain {
| def getName: String
| def getAlt: Int
| def getInfo = {
| println(getName + getAlt) }}
defined trait Mountain

31

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト

メソッド宣言

T-1

scala> trait Mountain {
| def getName: String
| def getAlt: Int
| def getInfo = {
| println(getName + getAlt) }}
defined trait Mountain

32

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト

メソッド定義

T-1

scala> trait Mountain {
| def getName: String
| def getAlt: Int
| def getInfo = {
| println(getName + getAlt) }}
defined trait Mountain

33

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > 具象クラス

extendsして作ります = ミックスイン

T-2

scala> trait Mountain {
| def getName: String
| def getAlt: Int
| def getInfo = {
| println(getName + getAlt) }}
defined trait Mountain
scala> class Fuji extends Mountain {
| def getName = "Fuji"
| def getAlt = 3776 }
defined class Fuji

34

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > 具象クラス

こうした方が親切です(Scala文化的にはつけないようですが)
T-3

scala> class Fuji extends Mountain {
| override def getName = "Fuji"
| override def getAlt = 3776 }
defined class Fuji

35

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > 抽象フィールド

valをつけてフィールド宣言

T-4

scala> trait Mountain {
| val name: String
| val alt: Int
| def getInfo = {
| println(name + alt) }}
defined trait Mountain

36

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > 抽象フィールド > 具象クラス

具象クラスの作成

T-5

scala> trait Mountain {
| val name: String
| val alt: Int
| def getInfo = {
| println(name + alt) }}
defined trait Mountain
scala> class Fuji extends Mountain {
| val name = "Fuji"
| val alt = 3776 }
defined class Fuji

37

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト

トレイトは複数ミックスインできます

38

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > 複数トレイトのミックスイン

1つ目のトレイト

T-6-1

scala> trait Mountain {
| val name: String
| val alt: Int
| def getInfo = {
| println(name + alt) }}
defined trait Mountain

39

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > 複数トレイトのミックスイン

2つ目のトレイト

T-6-2

scala> trait Mountain {
| val name: String
| val alt: Int
| def getInfo = {
| println(name + alt) }}
defined trait Mountain
scala> trait Volcano {
| def erupt() { println("erupted!") }}
defined trait Volcano

40

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > 複数トレイトのミックスイン

これらをミックスインすると、

T-6-3

scala> class Shinmoe extends Mountain with Volcano {
| val name = "ShinmoeDake"
↑2つ目からはwith
| val alt = 1421 }
defined class Shinmoe

41

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > 複数トレイトのミックスイン

それぞれの特性を持ったクラスを作ることができます

T-6-3

scala> class Shinmoe extends Mountain with Volcano {
| val name = "ShinmoeDake"
| val alt = 1421 }
defined class Shinmoe
scala> val shinmoe = new Shinmoe
shinmoe: Shinmoe = Shinmoe@1b827696
scala> shinmoe.alt
res2: Int = 1421
scala> shinmoe.erupt
erupted!

42

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
トレイト > まとめ

Scalaには抽象クラスもありますが、基本トレイトで事足ります

1. メソッドもフィールドも抽象化できる
trait Mountain {
def getName: String
val alt: Int }

2. 複数のトレイトをミックスインすることができる
class Shinmoe extends Mountain with Volcano {
val name = "ShinmoeDake"
val alt = 1421 }

43

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
オブジェクト指向要素編 > まとめ

Javaと文法が異なり、またJavaにはないトレ
イトという概念が存在しますが、Javaと大き
く異なる点はありません。

44

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
オブジェクト指向要素編 > まとめ

JDK 8にはトレイトに似た機能として仮想拡張
メソッド(Virtual Extension Methods)が追加
される予定です

45

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数プログラミング要素編

Scalaで関数プログラミング

46

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

高階関数とは

47

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

パラメータとして関数を取ったり、
関数を返す関数

48

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

高階関数の定義

FH-1

scala> def exec(num: Int, execFunc: Int => Boolean) = {
| execFunc(num) }
exec: (num: Int, execFunc: Int => Boolean)Boolean

49

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

execFuncというこの関数は

FH-1

scala> def exec(num: Int, execFunc: Int => Boolean) = {
| execFunc(num) }
exec: (num: Int, execFunc: Int => Boolean)Boolean

50

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

Int型の引数を受け取り

FH-1

scala> def exec(num: Int, execFunc: Int => Boolean) = {
| execFunc(num) }
exec: (num: Int, execFunc: Int => Boolean)Boolean

51

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

Booleanを返します

FH-1

scala> def exec(num: Int, execFunc: Int => Boolean) = {
| execFunc(num) }
exec: (num: Int, execFunc: Int => Boolean)Boolean

52

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

execはexecFuncを呼びます

FH-1

scala> def exec(num: Int, execFunc: Int => Boolean) = {
| execFunc(num) }
exec: (num: Int, execFunc: Int => Boolean)Boolean

53

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

execFuncの定義

FH-1

scala> def exec(num: Int, execFunc: Int => Boolean) = {
| execFunc(num) }
exec: (num: Int, execFunc: Int => Boolean)Boolean
scala> def isZero(num: Int) = {
| if (num == 0) true else false }
isZero: (num: Int)Boolean

54

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

使ってみましょう

FH-1

scala> def exec(num: Int, execFunc: Int => Boolean) = {
| execFunc(num) }
exec: (num: Int, execFunc: Int => Boolean)Boolean
scala> def isZero(num: Int) = {
| if (num == 0) true else false }
isZero: (num: Int)Boolean
scala> exec(0, isZero)
res1: Boolean = true

55

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数

使ってみましょう

FH-1

scala> def exec(num: Int, execFunc: Int => Boolean) = {
| execFunc(num) }
exec: (num: Int, execFunc: Int => Boolean)Boolean
scala> def isZero(num: Int) = {
| if (num == 0) true else false }
isZero: (num: Int)Boolean
scala> exec(0, isZero)
res1: Boolean = true
scala> exec(1, isZero)
res2: Boolean = false

56

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > ハンズオン

文字列をフィルタする関数を実行し、
フィルタの結果を表示する高階関数
を作ってみましょう

57

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > ハンズオン > コーディング例

高階関数

scala> def filterBy(str: String, filter: String => Boolean) = {
| if (filter(str)) println("passed")
| else println("not") }
filterBy: (str: String, filter: String => Boolean)Unit

58

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > ハンズオン > コーディング例

フィルタ関数

scala> def filterBy(str: String, filter: String => Boolean) = {
| if (filter(str)) println("passed")
| else println("not") }
filterBy: (str: String, filter: String => Boolean)Unit
scala> def lengthFilter(str: String) = {
| if (str.length > 10) true
| else false }
lengthFilter: (str: String)Boolean

59

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > ハンズオン > コーディング例

動作確認

scala> filterBy("明日は晴れると良いな", lengthFilter)
not

scala> filterBy("明日は雲ひとつない晴天となるでしょう",
lengthFilter)
passed

60

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化

同じ文字列に対していろんなフィルタをかけ
たい時

61

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化

高階関数

FH-2

scala> def filterBy(str: String, filter: String => Boolean) = {
| if (filter(str)) println("passed")
| else println("not") }
filterBy: (str: String, filter: String => Boolean)Unit

62

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化

を、カリー化してみる

FH-2

scala> def filterBy(str: String, filter: String => Boolean) = {
| if (filter(str)) println("passed")
| else println("not") }
filterBy: (str: String, filter: String => Boolean)Unit
scala> val curriedFilterBy = (filterBy _).curried
curriedFilterBy: String => ((String => Boolean) => Unit) =
<function1>
※カリー化
複数の引数を取る関数を、ある引数xを取り残
りの引数を取る関数に変換すること

63

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化

curriedFilterByはString型の引数を取り、

FH-2

scala> def filterBy(str: String, filter: String => Boolean) = {
| if (filter(str)) println("passed")
| else println("not") }
filterBy: (str: String, filter: String => Boolean)Unit
scala> val curriedFilterBy = (filterBy _).curried
curriedFilterBy: String => ((String => Boolean) => Unit) =
<function1>

64

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化

String型の引数からBoolean型の結果を返す関数を返しますよ
FH-2

scala> def filterBy(str: String, filter: String => Boolean) = {
| if (filter(str)) println("passed")
| else println("not") }
filterBy: (str: String, filter: String => Boolean)Unit
scala> val curriedFilterBy = (filterBy _).curried
curriedFilterBy: String => ((String => Boolean) => Unit) =
<function1>

65

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化

パラメータを1つしか指定してなくても呼べます

FH-2

scala> def filterBy(str: String, filter: String => Boolean) = {
| if (filter(str)) println("passed")
| else println("not") }
filterBy: (str: String, filter: String => Boolean)Unit
scala> val curriedFilterBy = (filterBy _).curried
curriedFilterBy: String => ((String => Boolean) => Unit) =
<function1>
scala> curriedFilterBy("1234567890")
res19: (String => Boolean) => Unit = <function1>
※部分適用
引数の一部だけを関数に適用すること

66

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化

lengthFilterを渡すと、フィルタ結果が表示されます

FH-2

scala> def filterBy(str: String, filter: String => Boolean) = {
| if (filter(str)) println("passed")
| else println("not") }
filterBy: (str: String, filter: String => Boolean)Unit
scala> val curriedFilterBy = (filterBy _).curried
curriedFilterBy: String => ((String => Boolean) => Unit) =
<function1>
scala> curriedFilterBy("1234567890")
res19: (String => Boolean) => Unit = <function1>

scala> curriedFilterBy("1234567890")(lengthFilter)
not
67

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化 > ハンズオン

文字列フィルタを追加し、カリー化した先ほ
どの高階関数を使ってフィルタしてみましょ
う

68

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化 > ハンズオン > コーディング例

フィルタ関数

scala> def matchingFilter(str: String) = {
| if (str.contains("scala")) true
| else false }
matchingFilter: (str: String)Boolean

69

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化 > ハンズオン > コーディング例

フィルタ対象文字列まで部分適用した関数オブジェクトを作り

scala> def matchingFilter(str: String) = {
| if (str.contains("scala")) true
| else false }
matchingFilter: (str: String)Boolean
scala> val func = curriedFilterBy("Scalaは面白い言語です")
func: (String => Boolean) => Unit = <function1>

70

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化 > ハンズオン > コーディング例

フィルタにかけてみます

scala> def matchingFilter(str: String) = {
| if (str.contains("scala")) true
| else false }
matchingFilter: (str: String)Boolean
scala> val func = curriedFilterBy("Scalaは面白い言語です")
func: (String => Boolean) => Unit = <function1>
scala> func(lengthFilter)
passed

71

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数 > 高階関数 > カリー化 > ハンズオン > コーディング例

フィルタにかけてみます

scala> def matchingFilter(str: String) = {
| if (str.contains("scala")) true
| else false }
matchingFilter: (str: String)Boolean
scala> val func = curriedFilterBy("Scalaは面白い言語です")
func: (String => Boolean) => Unit = <function1>
scala> func(lengthFilter)
passed
scala> func(matchingFilter)
not

72

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
関数編 > さいごに

高階関数と同様の機能がJDK 8には搭載される
予定です

73

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT編

SBT

74

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT編

目的
• SBTの簡単な説明
• ビルド定義ファイルを書いてみる
• jarファイルを作る

75

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > 概要

SBTとはJava, Scala向けビルドツールです (SBT = Simple Build Tool)

• コンパイル
• 実行
• テスト
• パッケージング
• ライブラリ管理
などを行えます。
プラグインで機能拡張が可能です。
76

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > 概要

今回は以下を取り上げます

•
•
•
•
•

コンパイル
実行
テスト
パッケージング
ライブラリ管理

77

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > 構成要素

SBTを利用する場合最低限必要なもの

1. SBT本体

→ インストール済み

1. Scalaソースコード

→ 以降で紹介

2. ビルド定義ファイル → 以降で紹介

78

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > 構成要素 > ディレクトリ構成

SBTプロジェクトのディレクトリ構成

src/
main/
resources/
scala/
java/
test/
resources/
scala/
java/

リソースファイルディレクトリ
Scalaソースファイルディレクトリ
Javaソースファイルディレクトリ
リソースファイルディレクトリ
Scalaソースファイル
Javaソースファイル

※src配下にある上記以外のディレクトリは無視されます

79

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ビルド定義ファイル

ビルド定義ファイルは2種類あります

1. build.sbt
• シンプルなビルド定義であればこちらでOK
• 各設定は1行あけて記述する

2. Build.scala
• build.sbtで事足りない場合にはこちらを使う
• Scalaのコードをそのまま書くことができる

80

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ビルド定義ファイル

今回はこちらを取り上げます

1. build.sbt
• シンプルなビルド定義であればこちらでOK
• 各設定は1行あけて記述する

2. Build.scala
• build.sbtで事足りない場合にはこちらを使う
• Scalaのコードをそのまま書くことができる

81

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ビルド定義ファイル > build.sbt

サンプル

name := "hello"
version := "1.0"
scalaVersion := "2.10.3"

82

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ビルド定義ファイル > build.sbt

プロジェクトの名前です

name := "hello"
version := "1.0"
scalaVersion := "2.10.3"

83

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ビルド定義ファイル > build.sbt

プロジェクトのバージョンです

name := "hello"
version := "1.0"
scalaVersion := "2.10.3"

84

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ビルド定義ファイル > build.sbt

使用するScalaのバージョンです

name := "hello"
version := "1.0"
scalaVersion := "2.10.3"

85

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン①

任意のディレクトリ配下に以下のファイルを作成します
S-1

1. build.sbt
name := "hello"
version := "1.0"
scalaVersion := "2.10.3"

2. Hello.scala

S-2

object Main {
def main(args: Array[String]): Unit = {
println("Hello")
}
※object = シングルトンオブジェクト
}

86

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン①

ディレクトリ構成

S-3

src/
build.sbt
main/
scala/
Hello.scala

87

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン①

SBTを起動してまずはコンパイル

$ cd /path/to/project
$ sbt
[info] Set current project to sbt (in build file:/path/to/project)
> compile

88

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン①

コンパイルされました

$ cd /path/to/project
$ sbt
[info] Set current project to sbt (in build file:/path/to/project)
> compile
[info] Updating {file:/path/to/project/}sbt...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /path/to/project/target/scala2.10/classes...
[success] Total time: 1 s, completed 2013/12/10 19:57:20
>

89

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン①

続いて実行してみます

> run

90

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン①

実行結果

> run
[info] Running Main
← 表示された!
Hello
[success] Total time: 0 s, completed 2013/12/10 19:59:30
>

91

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン②

パッケージングも簡単です

> package

92

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン②

実行結果

> package
[info] Packaging /path/to/project/target/scala-2.10/sbt_2.10-1.0.jar ...
← できた!
[info] Done packaging.
[success] Total time: 0 s, completed 2013/12/10 20:01:37

93

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン②

javaコマンドで実行してみます

> package
[info] Packaging /path/to/project/target/scala-2.10/sbt_2.10-1.0.jar ...
[info] Done packaging.
[success] Total time: 0 s, completed 2013/12/10 20:01:37
> exit
$ ls
$ build.sbt project src
target
$ cd target/scala-2.10/
$ ls
classes
sbt_2.10-1.0.jar
$ java -cp ./sbt_2.10-1.0.jar:/path/to/scala-library.jar Hello
※ホームディレクトリ/.sbt配下にあるはず

94

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン②

実行結果

> package
[info] Packaging /path/to/project/target/scala-2.10/sbt_2.10-1.0.jar ...
[info] Done packaging.
[success] Total time: 0 s, completed 2013/12/10 20:01:37
> exit
$ build.sbt project src
target
$ cd target/scala-2.10/
$ ls
classes
sbt_2.10-1.0.jar
$ java -cp ./sbt_2.10-1.0.jar:/path/to/scala-library.jar Hello
Hello

95

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン③

packageで生成するjarファイル名を
scala-handson_2.10-9.9.jar
に変えてみましょう

96

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン③ > 設定例

build.sbtを変えます

name := "scala-handson"
version := "9.9"
scalaVersion := "2.10.3"

97

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > ハンズオン③ > 設定例 > 実行結果

変わっていますね

> package
[info] Packaging /path/to/project/target/scala-2.10/scalahandson_2.10-9.9.jar ...
[info] Done packaging.
[success] Total time: 0 s, completed 2013/12/10 20:25:17

98

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > プラグイン

色々と便利なプラグインがあります

• sbt-eclipse (https://github.com/typesafehub/sbteclipse)
• Eclipseのプロジェクトファイルを生成できる

• xsbt-web-plugin (https://github.com/JamesEarlDouglas/xsbtweb-plugin)

• Web開発用のプラグイン

• sbt-assembly (https://github.com/sbt/sbt-assembly)
• オールインワンのjarファイルを生成できる

99

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
SBT > プラグイン

プラグインを利用すれば、大抵のことはでき
ます。
イプロスではJenkinsと併せて、ビルド、DB
マイグレーション、デプロイまでをSBTで実
施しています。

100

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
まとめ

まとめ

101

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
まとめ

イプロスでは広告系システムの開発にScalaを
導入し、REST APIサービス及びバッチを開発
しています。
Scalaの持つ概念の一部がJDK 8でも取り入れ
られる予定であることから、今日ご紹介した
内容は今後当たり前になっていくと思います。

102

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
まとめ

この勉強会がScalaを学ぶ契機となったならば
幸いです。

103

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
おしまい

ありがとうございました

104

COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED

Weitere ähnliche Inhalte

Andere mochten auch

Hubotを使ってbotをつくろう!
Hubotを使ってbotをつくろう!Hubotを使ってbotをつくろう!
Hubotを使ってbotをつくろう!Daisuke Kikuchi
 
CSS Nite LP38に行ってきた
CSS Nite LP38に行ってきたCSS Nite LP38に行ってきた
CSS Nite LP38に行ってきたYasuyuki Fujikawa
 
初心者Vimmerによるvim+rails開発
初心者Vimmerによるvim+rails開発初心者Vimmerによるvim+rails開発
初心者Vimmerによるvim+rails開発Daisuke Kikuchi
 
Vagrant勉強会アップロード用
Vagrant勉強会アップロード用Vagrant勉強会アップロード用
Vagrant勉強会アップロード用takeuchi-tk
 
Fluentd+elasticsearch+kibana(fluentd編)
Fluentd+elasticsearch+kibana(fluentd編)Fluentd+elasticsearch+kibana(fluentd編)
Fluentd+elasticsearch+kibana(fluentd編)Daisuke Kikuchi
 
Fluentdで本番環境を再現
Fluentdで本番環境を再現Fluentdで本番環境を再現
Fluentdで本番環境を再現Hiroshi Toyama
 
Markdownでドキュメント作成
Markdownでドキュメント作成Markdownでドキュメント作成
Markdownでドキュメント作成Yasuyuki Fujikawa
 
Presto As A Service - Treasure DataでのPresto運用事例
Presto As A Service - Treasure DataでのPresto運用事例Presto As A Service - Treasure DataでのPresto運用事例
Presto As A Service - Treasure DataでのPresto運用事例Taro L. Saito
 
Scala勉強会 初心者向けハンズオン前編
Scala勉強会 初心者向けハンズオン前編Scala勉強会 初心者向けハンズオン前編
Scala勉強会 初心者向けハンズオン前編takeuchi-tk
 
Re:dash Use Cases at iPROS
Re:dash Use Cases at iPROSRe:dash Use Cases at iPROS
Re:dash Use Cases at iPROSJumpei Yokota
 
爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話Kentaro Yoshida
 

Andere mochten auch (14)

Hubotを使ってbotをつくろう!
Hubotを使ってbotをつくろう!Hubotを使ってbotをつくろう!
Hubotを使ってbotをつくろう!
 
MBaaS - Parse
MBaaS - ParseMBaaS - Parse
MBaaS - Parse
 
CSS Nite LP38に行ってきた
CSS Nite LP38に行ってきたCSS Nite LP38に行ってきた
CSS Nite LP38に行ってきた
 
初心者Vimmerによるvim+rails開発
初心者Vimmerによるvim+rails開発初心者Vimmerによるvim+rails開発
初心者Vimmerによるvim+rails開発
 
Vagrant勉強会アップロード用
Vagrant勉強会アップロード用Vagrant勉強会アップロード用
Vagrant勉強会アップロード用
 
Fluentd+elasticsearch+kibana(fluentd編)
Fluentd+elasticsearch+kibana(fluentd編)Fluentd+elasticsearch+kibana(fluentd編)
Fluentd+elasticsearch+kibana(fluentd編)
 
Fluentdで本番環境を再現
Fluentdで本番環境を再現Fluentdで本番環境を再現
Fluentdで本番環境を再現
 
Enjoy the Ansible
Enjoy the AnsibleEnjoy the Ansible
Enjoy the Ansible
 
Markdownでドキュメント作成
Markdownでドキュメント作成Markdownでドキュメント作成
Markdownでドキュメント作成
 
Presto As A Service - Treasure DataでのPresto運用事例
Presto As A Service - Treasure DataでのPresto運用事例Presto As A Service - Treasure DataでのPresto運用事例
Presto As A Service - Treasure DataでのPresto運用事例
 
Scala勉強会 初心者向けハンズオン前編
Scala勉強会 初心者向けハンズオン前編Scala勉強会 初心者向けハンズオン前編
Scala勉強会 初心者向けハンズオン前編
 
Re:dash Use Cases at iPROS
Re:dash Use Cases at iPROSRe:dash Use Cases at iPROS
Re:dash Use Cases at iPROS
 
爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話爆速クエリエンジン”Presto”を使いたくなる話
爆速クエリエンジン”Presto”を使いたくなる話
 
re:dash is awesome
re:dash is awesomere:dash is awesome
re:dash is awesome
 

Kürzlich hochgeladen

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 

Kürzlich hochgeladen (8)

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 

Ipros techmeetup 20131218_scala_handson