SlideShare ist ein Scribd-Unternehmen logo
1 von 189
Scala 
@omiend
自己紹介 
@omiendです 
ネット上のオレ現実のオレ(通称:棺桶)
はじめに 
> 今日はなにをしてくれるのですか? 
今日は私が今ハマっているScala を紹介したいと 
おもいます 
需要と 
供給
はじめに 
> 対象者? 
日常的(?)にJavaが扱える人を対象とします 
が、私はまだまだScala勉強中ですので、そこらへん 
のご理解ある方(間違っていても優しくご指摘頂け 
る方)に限ります
はじめに 
> なぜJavaではなくScalaを? 
人と人のつながりを実現している個人的に大好きな 
Twitter が採用している、Scalaを勉強してみよ 
うと思った次第です
人類が宇宙に出たことにより出現したのが、ニュータイプです 
Javaという殻に閉じこもるのではなく、新しい分野を取り入れて、 
未来へとつなげて行きたいですね 
認めたくないもの 
だな…、自分自身 
の…若さ故の過ち 
というものを… 
人はいつか 
時間さえ支 
配すること 
ができるさ 
はじめに
はじめに 
Javaも素晴らしい言語です 
でなければ、ここまで実績のあるプログラミング言 
語にはならなかったでしょう
はじめに 
> では、この勉強会では何をめざしているのですか? 
Scalaに限らず、Java以外のさまざまなプログラミング言語にも 
目を向けて、必要があれば習得し、技術力の底上げを目指す意識 
が持てるように、一種の“起爆剤"のような勉強会になれれば良い 
なと思っています
はじめに 
> みなさんにおかれましては? 
へえ、あんたもJVMつかってんだ 
くらいの話半分で楽しんでいただければと!
はじめに 
> RubyかSwiftの方がいいんじゃないの? 
ぐぬぬ...
第1部 
JavaとScala
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - Scalaって? 
特徴その1 
スイス連邦工科大学(EPFL) のMartin Odersky先生と 
いうかたが作った、オブジェクト指向型プログラミ 
ング言語と関数型プログラミング言語の良い所取り 
をしたようなプログラミング言語 
※Martin Odersky先生 
JavaのGenerics<T>や、Javacを作った方
第1部:JavaとScala - Scalaって? 
特徴その2 
Javaと同じく、JVM上で動作 
コンパイルされるとclassファイルになる 
つまり、これまで作られてきたJavaプロダクトのす 
べてをScalaから使うことができる 
もちろん、classファイルになるのでJava側からも 
Scalaプロダクトを使うことができる
第1部:JavaとScala - Scalaって? 
特徴その3 
その他もろもろある 
のですが、割愛
第1部:JavaとScala - Scalaって? 
特徴その4(個人的に思う最大の特徴) 
コレクションのライブラリがちょーーー強力 
後ほどご紹介
第1部:JavaとScala - Scalaって? 
特徴その5(個人的に思う特徴) 
書いてて楽しい 
Java Scala 
← 体感→ 
※どっちも楽しい
第1部:JavaとScala - Scalaって? 
特徴その6(個人的に思う特徴) 
最新プログラミング言語SwiftがScalaに似ている 
Scalaやってるので割とスラスラ読めた
第1部:JavaとScala - Scalaって? 
特徴その-1(Scalaのあまり良くないところ) 
Date関連のAPIがない 
→あるかもしれないけど、みんなJavaのDateをよく 
使っている 
def nowDate: java.util.Date = new java.util.Date
第1部:JavaとScala - Scalaって? 
特徴その-2(Scalaのあまり良くないところ) 
とにかく学習コストが高い 
→私は今のところ半年強くらいやってるけど 
まだスラスラ書けず(それは私がカスだかr
第1部:JavaとScala - Scalaって? 
特徴その-3(Scalaのあまり良くないところ) 
コンパイルがクソ遅い 
頻繁に取り上げられるが、一部ではそのゲロ遅さが 
カワイイとの声も 
しかしsbtというのがあって...
第1部:JavaとScala - Scalaって? 
特徴その-4(Scalaのあまり良くないところ) 
仕事が無い 
SI業やってるうちはScalaなんてやらない方が良い 
脱SI目指すなら、ScalaでなくSwiftの方が良いんじゃないか 
とか思ってたり
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - REPL 
コマンドラインでScalaプログラムを実行できる機能 
Scalaをインストールすれば使うことができる 
ちょっとした動作確認をするときなど便利 
$ scala 
Welcome to Scala version 2.10.3 (Java HotSpot(TM) Client VM, Java 1.7.0_55). 
Type in expressions to have them evaluated. 
Type :help for more information. 
scala> 1 + 1 
res0: Int = 2 
scala>_
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - 変数宣言 
おなじみ 
String name = "シャア・アズナブル"; 
final String name = "アムロ・レイ"; 
Java
Scala 第1部:JavaとScala - 変数宣言 
varとvalがある 
var name: String = "シャア・アズナブル" 
val name: String = "アムロ・レイ" 
varはvariable(変数)という意味で再代入が可能 
valはvalue(値)という意味で再代入が不可能
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - 制御構文 
おなじみ 
if (true/false) {} else {} 
for (String val : list) {} 
Java
Scala 第1部:JavaとScala - 制御構文 
Javaに良く似ている 
if (true/false) {} else {} 
for (val <- list) {} 
もちろん、while文やdo~whileもあるけど割愛
Scala 第1部:JavaとScala - 制御構文 
for文の中にif文を書く事が出来る 
val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") 
for (name <- nameList if !name.isEmpty) { 
println(name) 
}
Scala 第1部:JavaとScala - 制御構文 
yieldを使うことで、処理結果をコレクションと 
して受け取る事が出来る 
val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") 
val resultList: List[String] = for (name <- nameList if !name.isEmpty) yield { 
name 
} 
println(resultList)
Java 第1部:JavaとScala - 制御構文 
Javaでやろうとするとこんな感じ 
List<String> nameList = Arrays.asList("シャア・アズナブル","","アムロ・レイ"); 
List<String> resultList = new ArrayList<String>(); 
for (String name : nameList) { 
if (name.isEmpty()) continue; 
resultList.add(name); 
} 
System.out.println(resultList);
第1部:JavaとScala - 制御構文 
for文のネストについて 
例えば、リストの中にリストが入る構造のデータが 
あったとする 
firstList 
secondList secondList 
ガンダム 
ジム 
ガンタンク 
ザクII 
グフ 
ジオング
Java 第1部:JavaとScala - 制御構文 
Javaで初期化するとこう 
List<List<String>> firstList = Arrays.asList( 
Arrays.asList("ガンダム","ジム","ガンタンク") 
,Arrays.asList("ザクII","グフ","ジオング") 
);
Scala 第1部:JavaとScala - 制御構文 
Scalaで初期化するとこう 
val firstList: List[List[String]] = List( 
List("ガンダム","ジム","ガンタンク") 
,List("ザクII","グフ","ジオング") 
)
Java 第1部:JavaとScala - 制御構文 
ネストforループのしかた 
Javaではおなじみ 
for (List<String> secondList : firstList) { 
for (String name : secondList) { 
System.out.println(name); 
} 
}
Scala 第1部:JavaとScala - 制御構文 
ネストforループのしかた 
セミコロンで区切って簡潔に記述可能 
for (secondList <- firstList ; name <- secondList) { 
println(name) 
}
第1部:JavaとScala - 制御構文 
パターンマッチについて(match~case) 
Javaのswitch~caseに似ているが、Scalaの 
match~caseは、主力といっても良いほどちょー強力 
な機能
Java 第1部:JavaとScala - 制御構文 
Javaのswitch~caseで書いた例 
String name = "シャア・アズナブル"; 
switch (name) { 
case "シャア・アズナブル": 
System.out.println("ジオン公国軍"); break; 
case "アムロ・レイ": 
System.out.println("地球連邦軍"); break; 
default: 
System.out.println("民間人"); break; 
}
Scala 第1部:JavaとScala - 制御構文 
Scalaのmatch~caseだとこう 
あまり変わりないけど... 
val name: String = "シャア・アズナブル" 
name match { 
case "シャア・アズナブル" => println("ジオン公国軍") 
case "アムロ・レイ" => println("地球連邦軍") 
case _ => println("民間人") 
}
Scalaのmatch~caseは型でもパターンマッチ出来た 
り... 
abstract class MS(val name: String) 
class NewGundam(override val name: String) extends MS(name) 
class Sazaby(override val name: String) extends MS(name) 
class Unicorn(override val name: String) extends MS(name) 
def matcher(ms: MS) = ms match { 
case mss: NewGundam => println(mss.name + " by ニューガンダム") 
case mss: Sazaby => println(mss.name + " by サザビー") 
case _ => println("所属不明機") 
} 
Scala 第1部:JavaとScala - 制御構文
Scala 第1部:JavaとScala - 制御構文 
他にも柔軟なパターンマッチを実現することができ 
たり 
List.range(1, 10) foreach { i => 
(i % 3, i % 5) match { 
case (0, 0) => println("FizzBuzz") 
case (0, _) => println("Fizz") 
case (_, 0) => println("Buzz") 
case _ => println(i) 
} 
}
第1部:JavaとScala - コレクションライブラリ 
mapとforeachの紹介 
Q.forループ処理ってなんのために使う? 
Scala
Scala 第1部:JavaとScala - コレクションライブラリ 
mapとforeachの紹介 
A.基本的にコレクションに対する値の操作
Scala 第1部:JavaとScala - コレクションライブラリ 
mapとforeachの紹介 
A.基本的にコレクションに対する値の操作 
さて、冒頭で「Scalaのコレクションにはちょー強力なライブラ 
リが多い」と述べたとおり 
実は、それらを利用すると、for文自体使わなくても良いケースが 
多かったりする
Scala 第1部:JavaとScala - コレクションライブラリ 
foreach 
例えば先ほどの下記は 
val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") 
for (name: String <- nameList if !name.isEmpty) { 
println(name) 
}
Scala 第1部:JavaとScala - コレクションライブラリ 
この様に記述できる 
val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") 
nameList.filter(x => !x.isEmpty).foreach { 
println(_) 
} 
省略できる 
nameList.filter(x => !x.isEmpty) foreach(println(_)) 
さらに省略できる(やりすぎると意味不明に...) 
nameList.filter(x => !x.isEmpty) foreach println
Scala 第1部:JavaとScala - コレクションライブラリ 
他にもいろいろなライブラリ 
この場合は 
val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") 
val resultList: List[String] = for (name: String <- nameList if !name.isEmpty) yield { 
name 
} 
filterメソッドを使えば一発 
val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") 
val resultList: List[String] = nameList.filter(x => !x.isEmpty)
Scala 第1部:JavaとScala - コレクションライブラリ 
map 
mapメソッドを使うと、より柔軟かつ簡潔な記述が 
出来る 
val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") 
val resultList:List[String] = nameList.filter(x => !x.isEmpty) map { name => 
name.replace("シャア・アズナブル","キャスバル・レム・ダイクン") 
} 
println(resultList)
Scala 第1部:JavaとScala - コレクションライブラリ 
foreachとmapの使い分け 
どちらも要素に対して順次操作するが 
・foreachはループ処理内だけで処理を完結 
・mapはループ処理から戻り値を取得 
する使い分けとなるとのこと
Scala 第1部:JavaとScala - コレクションライブラリ 
foreach 
要素による処理を実行 
nameList.filter(x => !x.isEmpty) foreach { name => 
println(name) 
}
Scala 第1部:JavaとScala - コレクションライブラリ 
map 
要素に変更を加える処理を実行 
ただし、Scalaでは副作用を引き起こす“要素そのものに変更を加える”事を良しとしないので、新しいコレクショ 
ンを生成する 
val resultList:List[String] = nameList.filter(x => !x.isEmpty) map { name => 
name.replace("シャア・アズナブル","キャスバル・レム・ダイクン") 
}
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - Tuple 
Scala 
Tuple 
Tuple(タプル)とは、複数のさまざまな型のデータ 
を一つにまとめる事が出来る機能 
さまざまなシーンで使える 
ただし、格納出来るオブジェクトは22個まで(タプ 
ル23問題)
Scala 第1部:JavaとScala - Tuple 
Tuple 
メソッドの戻り値を例に見てみる
第1部:JavaとScala - Tuple 
Javaのメソッドの戻り値は一つ 
public String getFirstName() { 
return this.firstName; 
} 
public String getLastName() { 
return this.lastName; 
} 
public int getAge() { 
return this.age; 
} 
public String getFullName() { 
return this.firstName + this.lastName; 
} 
Java
Scala 第1部:JavaとScala - Tuple 
メソッドの戻り値にTupleを使えば... 
case class Employee(val firstName: String, val lastName: String, val age: Int) { 
def allData = (firstName, lastName, age) // Tupleを返却する 
} 
val emp: Employee = Employee("kazuomi","Endo",31) 
val allData = emp.allData 
println(allData._1) // kazuomi 
println(allData._2) // endo 
println(allData._3) // 31 
println(allData._4) // これはコンパイルエラー
Scala 第1部:JavaとScala - Tuple 
Tuple 
さまざまなシーンで使える 
ただし、格納出来るオブジェクトは22個まで(タプ 
ル23問題)
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - 無名関数Scala 
無名関数 
先ほど説明したコレクションの所で、下記の様な見 
慣れない書き方があった 
nameList.filter(x => !x.isEmpty)
Scala 第1部:JavaとScala - 無名関数 
無名関数 
これはJavaで言う無名クラスの様なもので、省略せ 
ずに書くとこうなる 
nameList.filter { 
(x: String) => { 
!x.isEmpty 
} 
}
Scala 第1部:JavaとScala - 無名関数 
無名関数 
ここら辺が無名関数 
nameList.filter { 
(x: String) => { 
!x.isEmpty 
} 
}
Scala 第1部:JavaとScala - 無名関数 
無名関数 
ワンライナーの場合は省略した方が読みやすくなっ 
たり、ならんかったり 
nameList.filter(x => !x.isEmpty)
Scala 第1部:JavaとScala - 無名関数 
無名関数 
ちなみに、コレクションで説明した例の記述をあえ 
てJavaで書くと 
val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") 
val filteredList: List[String] = nameList.filter(x => !x.isEmpty) 
println(filteredList)
Java 第1部:JavaとScala - 無名関数 
無名クラス 
interface MyList { 
public List<String> filter(List<String> nameList); 
} 
MyList filterList = new MyList() { 
public List<String> filter(List<String> nameList) { 
List<String> returnList = new ArrayList<String>(); 
for (String name : nameList) { 
if (name != null && name != ””) { 
returnList.add(name); 
} 
} 
return returnList; 
} 
};
Java 第1部:JavaとScala - 無名関数 
ここらへんが無名クラス 
interface MyList { 
public List<String> filter(List<String> nameList); 
} 
MyList filterList = new MyList() { 
public List<String> filter(List<String> nameList) { 
List<String> returnList = new ArrayList<String>(); 
for (String name : nameList) { 
if (name != null && name != ””) { 
returnList.add(name); 
} 
} 
return returnList; 
} 
};
Java 第1部:JavaとScala - 無名関数 
実行 
List<String> nameList = Arrays.asList("シャア・アズナブル","","アムロ・レイ"); 
List<String> filteredList = filterList.filter(nameList); 
System.out.println(filteredList);
Java 第1部:JavaとScala - 無名関数 
まあ、Listの要素をフィルターするだけに普通こん 
なことはしないけど、無名関数の参考程度までに
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - クラスとオブジェクト 
クラスの定義 
まあおなじみでしょうか 
class MyClass { 
} 
Java
第1部:JavaとScala - クラスとオブジェクト 
クラスの定義 
ほとんどJavaと同様 
class MyClass { 
} 
Scala
第1部:JavaとScala - クラスとオブジェクト 
クラスの定義 
コンストラクタ 
class MyClass { 
public MyClass() { 
System.out.println("Hello World!"); 
} 
} 
Java
第1部:JavaとScala - クラスとオブジェクト 
クラスの定義 
コンストラクタはJavaで言うメンバに定義する 
class MyClass { 
// ここにコンストラクタの処理を定義 
println("Hello World!") 
} 
Scala
第1部:JavaとScala - クラスとオブジェクト 
クラスの定義 
引数ありのコンストラクタ 
class MyClass { 
public MyClass(String name) { 
} 
} 
Java
第1部:JavaとScala - クラスとオブジェクト 
クラスの定義 
Scalaの場合、クラスの定義に引数を記述 
class MyClass(name: String) { 
// ここにコンストラクタの処理を定義 
println("Hello World! %s".format(name)) 
} 
--- 
val nameC = new MyClass("アムロ!") 
Hello World! アムロ! 
nameC: MyClass = MyClass@1835d850 
Scala
第1部:JavaとScala - クラスとオブジェクト 
クラスの定義 
二つ以上のコンストラクタ(オーバーロード) 
class MyClass { 
public MyClass(String name) { 
} 
public MyClass(String name, int age) { 
} 
} 
Java
第1部:JavaとScala - クラスとオブジェクト 
クラスの定義 
Scalaでは2つめ以降のコンストラクタを「補助コンストラク 
タ」と言い、その前に定義されたコンストラクタを呼び出す必要 
がある 
class MyClass(name: String) { 
println("Hello World! %s".format(name)) 
// 補助コンストラクタ 
def this(name: String, age: Int) = { 
this(name) 
println("Hello World! %s %d".format(name, age)) 
} 
} 
Scala
第1部:JavaとScala - クラスとオブジェクト 
Scala 
オブジェクトの定義 
Scalaにはstaticの概念は無いが、シングルトンオブ 
ジェクト(アプリ内に1つしかないオブジェクト) 
を定義する事が出来る 
object MyObject { 
val limit = 1000 
}
Scala 
第1部:JavaとScala - クラスとオブジェクト 
コンパニオンオブジェクトの定義 
同名のクラスとオブジェクトを同一ソースに定義す 
ると、そのオブジェクトはコンパニオンオブジェク 
トと呼ばれるものになり、オブジェクトとクラス間 
でprivateメンバへのアクセスが可能となる 
主にクラスを生成する役目として利用する(ファク 
トリー)
第1部:JavaとScala - クラスとオブジェクト 
コンパニオンオブジェクトの定義 
class MyName(name: String) { 
println("Hello World! %s".format(name)) 
} 
object MyName { 
// applyの定義が必要 
def apply(name: String) = new MyName(name) 
} 
MyName.apply("Name") // Hello World! TEST 
MyName("Name") // applyは少し特殊で、省略可能 
Scala
第1部:JavaとScala - クラスとオブジェクト 
Scala 
ケースクラスの定義 
いくつかの便利なメソッドやコンパニオンオブジェ 
クトが自動的に生成される 
コンストラクタに対するパターンマッチが利用出来 
たり、値を保持するDTOとしての定義に利用 
case class MyClass(name: String) { 
println("Hello World! %s".format(name)) 
}
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - Option型Scala 
Option型 
値があるかないかを表す箱の様なもの 
nullの可能性がある変数を、Option型でラップをする 
ことにより、より安全なプログラミングを実現する 
仕組み 
モナドという概念を使うときにも必要?
Scala 第1部:JavaとScala - Option型 
Option型 
Option型のサブクラスには 
● Some型:値がある場合 
● None型:値がない場合 
がある
Scala 第1部:JavaとScala - Option型 
Option型 
まだうまく説明できず(笑) 
なので、Mapを使ってニュアンスだけで...
Java 第1部:JavaとScala - Option型 
Mapを使った例 
下記はコンパイルエラーにならず、実行してもエラ 
ーにはならない 
final Map<String, String> pilotMap = new HashMap<String, String>() {{ 
put("1", "ガンダム"); 
put("2", null); }}; 
System.out.println(pilotMap.get("1").length());
Java 第1部:JavaとScala - Option型 
Mapを使った例 
しかし、key:2を指定すると、実行時にヌルポが発 
生する(当たり前) 
final Map<String, String> pilotMap = new HashMap<String, String>() {{ 
put("1", "ガンダム"); 
put("2", null); }}; 
System.out.println(pilotMap.get("2").length());
Java 第1部:JavaとScala - Option型 
Mapを使った例 
しかし、key:3を指定しても、実行時にヌルポが発 
生する(当たり前) 
final Map<String, String> pilotMap = new HashMap<String, String>() {{ 
put("1", "ガンダム"); 
put("2", null); }}; 
System.out.println(pilotMap.get("3").length());
Java 第1部:JavaとScala - Option型 
Mapを使った例 
さて、key:2とkey:3指定した時、どちらも実行時に 
ヌルポで落ちたが 
● 値がなくてヌルポが発生したのか 
● keyがなくてヌルポが発生したのか 
一見どちらが原因でエラーとなったのか不明
Java 第1部:JavaとScala - Option型 
Mapを使った例 
対応するとしたら下記の様な対応か? 
・keyの存在チェック 
・nullチェックする 
しかし、そもそもコンパイラは、これらの対応がさ 
れているか分からない
Java 第1部:JavaとScala - Option型 
Mapを使った例 
final Map<String, String> pilotMap = new HashMap<String, String>() {{ 
put("1", "ガンダム"); 
put("2", null); }}; 
if (pilotMap.containsKey("1") && pilotMap.get("1") != null) 
System.out.println(pilotMap.get("1").length()); 
if (pilotMap.containsKey("2") && pilotMap.get("2") != null) 
System.out.println(pilotMap.get("2").length()); 
if (pilotMap.containsKey("3") && pilotMap.get("3") != null) 
System.out.println(pilotMap.get("3").length());
Scala 第1部:JavaとScala - Option型 
Mapを使った例 
こうしたコンパイルチェック時に検出できない潜在 
バグを極力なくしていくのが、ScalaのOption型(だ 
と思っている) 
では実際にどうやって先ほどの問題を解決するのか
Scala 第1部:JavaとScala - Option型 
Mapを使った例 
そこでパターンマッチ(match~case)を使う 
Option型は、値が存在する場合はSome型、値が存 
在しない場合None型を返すため、パターンマッチで 
それらを検出する
Scala 第1部:JavaとScala - Option型 
Mapを使った例 
val pilotMap: Map[String, String] = Map("1" -> "ガンダム", "2" -> null) 
def checkValue(key: String) = pilotMap.get(key) match { 
case Some(v) if v == null => "nullです" 
case Some(v) => "%sです" format v 
case None => "値はありません" 
} 
println(checkValue("1")) // ガンダムです 
println(checkValue("2")) // nullです 
println(checkValue("3")) // 値はありません
Scala 第1部:JavaとScala - Option型 
Mapを使った例 
値にnullが入るのは仕方のないことなので、やはり 
nullチェックは必要 
しかし、Mapのkeyが存在しない場合については、 
Noneが帰ってくるため、明示的な実装が可能になる
Scala 第1部:JavaとScala - Option型 
Mapを使った例 
もちろん、Javaでもkeyと値が存在するかどうかの 
チェックメソッドを一つ作れば良い話だけど、標準 
で安全なプログラミングをサポートしているという 
感じが良い
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - 引数について(+部分適用とカリー化) 
引数について- 通常 
def f(arg1: String,arg2: String): String = { 
"%sと%s".format(arg1,arg2) 
} 
println(f("引数①","引数②")) 
---実行結果--- 
引数①と引数② 
Scala
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
引数について- 変数名指定 
def f(arg1: String,arg2: String): String = { 
"%sと%s".format(arg1,arg2) 
} 
println(f(arg1 = "引数①",arg2 = "引数②")) 
---実行結果--- 
引数①と引数②
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
引数について- 可変長引数 
def f(args: String*) = args foreach println 
f("引数①","引数②") 
---実行結果--- 
引数① 
引数②
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
引数について- 可変長引数 
引数が可変長引数の場合、コレクションも渡すこと 
ができる(ただし、_*をつける必要あり) 
def f(args: String*) = args foreach println 
f(List("引数①","引数②"): _*) 
---実行結果--- 
{同じ}
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
引数について- 初期値 
def f(arg1: String,arg2: String = "引数②"): String = { 
"%sと%s".format(arg1,arg2) 
} 
println(f("引数①")) 
---実行結果--- 
引数①と引数②
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
引数について- 初期値 
これはコンパイラがどの引数に入れたら良いのか分 
からないので、コンパイルエラーとなる 
def f(arg1: String = "引数①",arg2: String): String = { 
"%sと%s".format(arg1,arg2) 
} 
println(f("引数②"))
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
引数について- 初期値 
変数名指定すればOK 
def f(arg1: String = "引数①",arg2: String): String = { 
"%sと%s".format(arg1,arg2) 
} 
println(f(arg2 = "引数②")) 
---実行結果--- 
引数①と引数②
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
引数について- 初期値 
指定した値を優先する 
def f(arg1: String = "引数①",arg2: String): String = { 
"%sと%s".format(arg1,arg2) 
} 
println(f(arg1 = "引数③",arg2 = "引数②")) 
---実行結果--- 
引数③と引数②
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
部分適用 
メソッドの引数の一部を固定し、新たに関数オブジ 
ェクト(変数)を生成できるしくみ
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
部分適用 
def f1(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) 
val f2 = f1("引数①", _:String) // 引数1を固定して関数オブジェクトを作成 
println(f2("引数②")) 
val f3 = f1(_:String, "引数②") // 引数2を固定して関数オブジェクトを作成 
println(f3("引数①")) 
---実行結果--- 
引数①と引数② 
引数①と引数②
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
カリー化 
メソッドの引数を分け、第1引数から順次受け取る 
メソッドを新たに定義出来るしくみ
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
カリー化 
// メソッドを定義 
def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) 
※当該メソッドの処理内容 
methodは二つの引数を取り、それぞれの値を"%sと%s"にバインドStringInterpolationし、 
String型として返します。
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
カリー化 
// メソッドを定義 
def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) 
val functionObject = method _ // メソッドを関数オブジェクト化
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
カリー化 
// メソッドを定義 
def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) 
val functionObject = method _ // メソッドを関数オブジェクト化 
val curreidFunction = functionObject.curried // 関数オブジェクトをカリー化
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
カリー化 
// メソッドを定義 
def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) 
val functionObject = method _ // メソッドを関数オブジェクト化 
val curreidFunction = functionObject.curried // 関数オブジェクトをカリー化 
// 第1引数を指定し、第2引数を引数として受け取る関数オブジェクトを作成 
val function1 = curreidFunction("引数①")
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
カリー化 
// メソッドを定義 
def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) 
val functionObject = method _ // メソッドを関数オブジェクト化 
val curreidFunction = functionObject.curried // 関数オブジェクトをカリー化 
// 第1引数を指定し、第2引数を引数として受け取る関数オブジェクトを作成 
val function1 = curreidFunction("引数①") 
println(function1("引数②-1")) // 第2引数を指定して処理を実行 
---実行結果--- 
引数①と引数②-1
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
カリー化 
初めからカリー化されたメソッドを定義した場合 
// メソッドを定義 
def method(arg1: String) = (arg2: String) => "%sと%s".format(arg1, arg2) 
// 第1引数を指定し、第2引数を引数として受け取る関数オブジェクトを作成 
val function1 = method("引数①") 
println(function1("引数②-1")) // 第2引数を指定して処理を実行 
---実行結果--- 
引数①と引数②-1
Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 
カリー化 
いっぺんに実行することも可能 
// メソッドを定義 
def method(arg1: String) = (arg2: String) => "%sと%s".format(arg1, arg2) 
println(method("引数①")("引数②-1")) 
---実行結果--- 
引数①と引数②-1
第1部:JavaとScala 
● Scalaって? 
● REPL 
● 変数宣言 
● 制御構文/コレクションのライブラリ 
● Tuple 
● 無名関数 
● クラスとオブジェクト 
● Option型 
● 引数について(+部分適用とカリー化) 
● クロージャ
第1部:JavaとScala - クロージャScala 
クロージャ 
まずは静的スコープのお話 
ブロックAの変数xとブロックBの変数xは同じ名前をもつがブロックが異なる為別のも 
のである。またBの中ではCのようにさらに内側の変数を見ることができず、逆にCから 
はBのxとCのyが見える※Wikipediaから引用 
A {var x} // A内のみ参照可能 
B { 
var x // BとCから参照可能で、A内のxとは別物 
C {var y} // C内のみ参照可能 
}
Scala 第1部:JavaとScala - クロージャ 
クロージャ 
よくある例 
var count = 100 
def counter() = { 
var count = 200 
() => { 
count += 10 
count 
} 
} 
val c1 = counter() 
println(c1()) 
println(c1())
Scala 第1部:JavaとScala - クロージャ 
クロージャ 
この場合、無名関数()が参照するcountは、直近スコ 
ープにある200で初期化されたものが利用される 
var count = 100 
def counter() = { 
var count = 200 
() => { 
count += 10 
count 
} 
}
第1部 
〜完〜
Seven Samurai
第2部 
Play Framework
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
第2部:Play Framework 
Play Frameworkって? 
JavaとScalaどちらでも実装出来るWebアプリケー 
ションフレームワーク 
・MVC 
・ホットリローディングあり 
・ステートレス(セッション無し)
第2部:Play Framework 
Play Frameworkって? 
1.X系と2.X系で、まったくの別物 
2014/07現在は2.3が最新
第2部:Play Framework 
Play Frameworkって? 
実はただのsbt
第2部:Play Framework 
Play Frameworkって? 
Nettyサーバーが組み込まれており、それを使って実 
行するように設計されている 
けど 
Warに固めてデプロイもできる(非推奨?)
第2部:Play Framework 
Play Frameworkって?
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Scala Java 第2部:Play Framework 
インストール 
2.2まではPlayのzipをダウンロードして、$PATHに 
通すだけで良かった 
2.3からは下記サイトからActivatorを取得し、$PATH 
に追加するか、「brew install typesafe-sctivator」す 
る 
Playframework 
http://www.playframework.com/
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Scala Java 第2部:Play Framework 
プロジェクトの作成、起動 
まずは「activator new」コマンドを実行する 
$ activator new 
~割愛~
Java 第2部:Play Framework 
プロジェクトの作成、起動 
作成するプロジェクトの形式を選択する 
例ではScalaを選択 
Scala 
~割愛~ 
Choose from these featured templates or enter a template name: 
1) minimal-java 
2) minimal-scala 
3) play-java 
4) play-scala 
(hit tab to see a list of all templates) 
> 4
第2部:Play Framework 
プロジェクトの作成、起動 
アプリケーション名を入力する 
例では「My App」を入力 
Scala Java 
~割愛~ 
Enter a name for your application (just press enter for 'play-scala') 
> MyApp 
OK, application "MyApp" is being created using the "play-scala" template. 
~割愛~
Scala Java 
第2部:Play Framework 
プロジェクトの作成、起動 
作成された「My App」ディレクトリに移動し 
「activator run」コマンドを実行して移動 
$ cd MyApp/ 
$ activator run 
~割愛~ 
[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Scala Java 第2部:Play Framework 
リクエスト→レスポンスの流れ 
まず初めに、トップ画面のリクエストを行う 
http://localhost:9000/
Scala Java 第2部:Play Framework 
リクエスト→レスポンスの流れ 
すると、「conf/routes」ファイルに記載されている下記の内容を 
もとに、呼び出す処理を解決する 
GET / controllers.Application.index 
→ app/controllers/Application.java 
→ app/controllers/Application.scala 
のindexメソッド
Java 第2部:Play Framework 
リクエスト→レスポンスの流れ 
JavaのControllerはこのような記述 
public static Result index() { 
Ok(index.render("Hello World!")); 
}
Scala 第2部:Play Framework 
リクエスト→レスポンスの流れ 
ScalaのContrllerはこの様な記述 
def index() = Action { implicit request => 
Ok(html.index("Hello World!")) 
}
Scala Java 第2部:Play Framework 
リクエスト→レスポンスの流れ 
次に、Okメソッドに指定したページをレスポンスと 
して返す 
app/views/index.scala.html
Scala Java 第2部:Play Framework 
app/views/index.scala.html 
画面の定義はJavaとScalaほぼ同じ 
@(text: String) 
@main("indexページ") { 
<p>@text</p> 
}
Scala Java 第2部:Play Framework 
app/views/index.scala.html 
@はじまりの箇所はすべてScalaのロジック 
@(text: String) 
@main("indexページ") { 
<p>@text</p> 
}
Scala Java 第2部:Play Framework 
app/views/index.scala.html 
さらにここからmainと定義されたページテンプレー 
トを呼び出す 
@main("indexページ") {} 
→ app/views/main.scala.html
Scala Java 第2部:Play Framework 
リクエスト→レスポンスの流れ 
app/views/main.scala.html 
contentに先述のindexページが格納されている 
@(title: String)(content: Html) 
<html> 
<head> 
<title>@title</title> 
</head> 
<body> 
@content 
</body> 
</html>
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Scala Java 第2部:Play Framework 
ルーティング 
リクエストパラメータは下記の様に指定する 
View 
<a href="@routes.Application.index(1)">トップ</a> 
conf/routes 
GET / controllers.Application.index(p: Int)
Java 第2部:Play Framework 
ルーティング 
リクエストパラメータは下記の様に指定する 
Controller 
public static Result index(int p) { 
Ok(index.render("Hello World!")); 
}
Scala 第2部:Play Framework 
ルーティング 
リクエストパラメータは下記の様に指定する 
Controller 
def index(p: Int) = Action { implicit request => 
Ok(html.index("Hello World!")) 
}
Scala Java 第2部:Play Framework 
ルーティング 
下記の様に記述することで、初期値を指定でき 
る 
conf/routes 
GET / controllers.Application.index(p: Int ?= 1)
Scala Java 第2部:Play Framework 
ルーティング 
下記の様に記述することで、リクエストパラメータ 
をURLの一部に指定できる 
conf/routes 
GET /:p controllers.Application.index(p: Int) 
URL 
http://localhost:9000/1
Scala Java 第2部:Play Framework 
ルーティング 
リバースルーティングも可能(初期指定済み) 
conf/routes 
GET /assets/*file controllers.Assets.at(path="/public", file) 
View 
<script type="text/javascript" 
src="@routes.Assets.at("javascripts/bootstrap.min.js")"></script>
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Scala Java 第2部:Play Framework 
Database接続設定 
Database接続を行うには、下記ファイルにエンドポ 
イントを記述する 
conf/application.conf
Scala Java 第2部:Play Framework 
Database接続設定 
PlayにはH2が組み込まれており、下記の記述を有効 
化するだけで利用できる 
db.default.driver=org.h2.Driver 
db.default.url="jdbc:h2:mem:play" 
db.default.user=sa 
db.default.password=""
Scala Java 第2部:Play Framework 
Database接続設定 
MySQLを利用する場合 
下記の様にエンドポイントを記述し... 
db.default.driver=com.mysql.jdbc.Driver 
db.default.url="jdbc:mysql://localhost:3306/{DATABASE_NAME} 
db.default.user={USER_NAME} 
db.default.password="{PASS_WORD}"
Scala Java 第2部:Play Framework 
Database接続設定 
MySQLを利用する場合 
Configuration Fileに下記の様な記述を行う 
build.sbt 
val appDependencies = Seq( 
// Add your project dependencies here, 
"mysql" % "mysql-connector-java" % "5.1.20" 
)
Scala Java 第2部:Play Framework 
Database接続設定 
Configuration Fileはsbt※のものなので詳細は割愛 
※簡単に言うと、必要なライブラリを管理出来るビ 
ルドツール
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Scala Java 第2部:Play Framework 
Revolution機能 
play runすると、 
conf¥evolutions¥default¥1.sql 
というファイルに定義されたSQLを実行してくれる。 
開発中のDB定義マイグレーションに便利。
Scala Java 第2部:Play Framework 
Evolution機能 
http://localhost:9000/ にアクセスすると、下記 
の様にDBを構築するスクリプトが表示される 
ので、「Apply this script now!」を押下する。 
※スクリプトはdefault¥1.sqlの中身。
Scala Java 第2部:Play Framework 
Evolution機能
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Scala Java 第2部:Play Framework 
DB操作 
親テーブル(1)と子テーブル(N)という2つのテ 
ーブルが存在するデータベースがあったとする。 
各テーブルからデータを登録・読取・更新・削 
除する場合の実装方法例を記載する。
Java 第2部:Play Framework 
DB操作 
Java版では、Ebeanを利用(Playに同梱済み)。 
conf/application.conf 
に 
ebean.default="models.*" 
を記述してモデルクラス格納パッケージを指定する。 
Ebean 
http://www.avaje.org/ebean/documentation.html
Java 第2部:Play Framework 
DB操作 
app/models 
パッケージに、親テーブルと子テーブル用の 
「@Entity」「extends Model」 
を適用したモデルクラスを作成する。
Java 第2部:Play Framework 
DB操作- 親テーブル定義例 
@Entity 
public class Parent extends Model { 
private static final long serialVersionUID = 1L; 
@Id 
public Long id; 
@Required 
public String name; 
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent") 
public List<Child> child = new ArrayList<Child>(); 
protected Timestamp createDate; 
@Version 
protected Timestamp updateDate; 
public static Finder<Long,Parent> find = new Finder<Long,Parent>(Long.class, Parent.class); 
}
Java 第2部:Play Framework 
DB操作- 子テーブル定義例 
@Entity 
public class Child extends Model { 
private static final long serialVersionUID = 1L; 
@Id 
public Long id; 
@Required 
public String name; 
@ManyToOne 
@JoinColumn(name = "child") 
public Parent parent; 
protected Timestamp createDate; 
@Version 
protected Timestamp updateDate; 
public static Finder<Long,Child> find = new Finder<Long,Child>(Long.class, Child.class); 
}
Java 第2部:Play Framework 
DB操作 
play runすると、 
conf¥evolutions¥default¥1.sql 
を作成してくれる。 
Ebeanの良いところ。
Java 第2部:Play Framework 
DB操作 
実際のデータ取得は、先のモデルクラスに定義した 
public static Finder<Long,Parent> find 
= new Finder<Long,Parent>(Long.class, Parent.class); 
を使用する。
Java 第2部:Play Framework 
DB操作 
データ取得例 
List<Parent> parentList = Parent.find.findList(); 
List<Parent> parentList = Parent.find.where().eq(“name”, “omiend").findList(); 
List<Parent> parentList = Parent.find.setFirstRow(0).setMaxRows(10).findList(); 
int rowCount = Parent.find.findRowCount();
第2部:Play Framework 
Scala 
DB操作 
Scala版ではScalaikeJDBCがトレンドだが、私は勉 
強中なので、今回は実際に使ったAnormを紹介
第2部:Play Framework 
DB操作 
Configuration Fileに下記の様な記述を行う 
build.sbt 
val appDependencies = Seq( 
// Add your project dependencies here, 
anorm 
) 
Scala
第2部:Play Framework 
DB操作 
モデルクラスを用意する 
下記は先述のケースクラスとオブジェクト(コンパニオンオブジェクト)を一緒に 
ParentModel.scalaに定義した例 
DDLはオブジェクト内に定義して行く事となる 
case class Parent(id: Pk[Long] = NotAssigned 
,name: String 
,var createDate: Option[Date] 
,var updateDate: Option[Date]) { 
} 
object Parent { 
} 
Scala
第2部:Play Framework 
Scala 
DB操作 
取得したデータをモデルにマッピングする為の定義 
をする 
object Parent { 
val simple = { 
get[Pk[Long]]("parent.id") ~ 
get[String]("parent.name") ~ 
get[Date]("parent.create_date") ~ 
get[Date]("parent.update_date") map { 
case id~name~createDate~updateDate => Parent(id, name, Option(createDate), Option(updateDate)) 
} 
} 
}
第2部:Play Framework 
DB操作 
DDLを定義する 
object Parent { 
def findByName(name: String): Seq[Parent] = { 
DB.withConnection { implicit connection => 
SQL(""" 
select * 
from parent 
where name = {name} 
""").on( 
'name -> name 
).as(Parent.simple *) 
}}} 
Scala
第2部:Play Framework 
DB操作 
データ取得例 
val resultList = Parent.findByName(“omiend") 
Scala
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Java 
第2部:Play Framework 
Formの定義 
Javaの場合、下記の様にモデルクラスを利用して 
Formを作成する 
Form<Parent> parentForm = form(Parent.class); 
return ok(create.render(parentForm));
第2部:Play Framework 
Formの定義 
Scalaの場合、下記の様なモデルへのマッピングオブ 
ジェクトを作成する 
val parentForm = Form( 
mapping( 
"id" -> ignored(NotAssigned: Pk[Long]), 
"name" -> nonEmptyText, 
"createDate" -> optional(date("yyyy-MM-dd")), 
"updateDate" -> optional(date("yyyy-MM-dd")) 
)(Parent.apply)(Parent.unapply) 
) 
Ok(html.create(parentForm)) 
Scala
Scala Java 第2部:Play Framework 
Formの定義- Viewの定義例 
@(parentForm: Form[Parent]) 
@import helper._ 
@main() { 
@form(routes.Application.insertParent()) { 
<fieldset> 
@inputText(parentForm("name")) 
</fieldset> 
<div class="actions"> 
<input type="submit" value="登録"> or 
<a href="@routes.Application.index()" class="btn">Cancel</a> 
</div> 
} 
}
Scala Java 第2部:Play Framework 
Formの定義- Viewの定義例
Scala Java 第2部:Play Framework 
Formの定義- Viewの定義例 
POST先のroutes設定はこんな感じ 
conf/routes 
POST /insertParent 
controller.Application.insertParent
第2部:Play Framework 
● Play Frameworkって? 
● インストール 
● プロジェクトの作成・起動 
● リクエスト→レスポンスの流れ 
● ルーティング 
● Database接続設定 
● Evolution機能 
● DB操作 
● Formの定義 
● まとめ(JavaとScala比べ)
Scala Java 第2部:Play Framework 
まとめ(Java版とScala版比べ) 
● Viewの定義方法はどちらも同じ 
● EbeanとAnormでは、Ebeanの方が実装が容易 
● Formの定義もJava版の方が容易 
● Java版でも、Javaでの実装はControllerとModelだ 
けで、他はすべてScalaで実装する必要がある 
● ビルドはScalaのsbtが利用されるので、その辺の 
知識は必須
時間があれば 
ライブコーディングデモ
第2部 
〜完〜
以上で今回の 
Scala勉強会は終了です 
ご清聴ありがとうございました

Weitere ähnliche Inhalte

Was ist angesagt?

rpscala35-scala2.9.0
rpscala35-scala2.9.0rpscala35-scala2.9.0
rpscala35-scala2.9.0Kenji Yoshida
 
Reladomo in Scala #scala_ks
Reladomo in Scala #scala_ks Reladomo in Scala #scala_ks
Reladomo in Scala #scala_ks Hiroshi Ito
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Naoki Aoyama
 
Javaプログラミング入門【第7回】
Javaプログラミング入門【第7回】Javaプログラミング入門【第7回】
Javaプログラミング入門【第7回】Yukiko Kato
 
Javaプログラミング入門【第5回】
Javaプログラミング入門【第5回】Javaプログラミング入門【第5回】
Javaプログラミング入門【第5回】Yukiko Kato
 
Scala EE 7 Essentials
Scala EE 7 EssentialsScala EE 7 Essentials
Scala EE 7 Essentialstnoda
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?Kenji Nakamura
 
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriWhy Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriYuta Okamoto
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行guest5f4320
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用nagise
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPIAkihiro Ikezoe
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2Masatoshi Tada
 
Shibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R についてShibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R についてtnoda
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門Makoto Fukuhara
 

Was ist angesagt? (18)

rpscala35-scala2.9.0
rpscala35-scala2.9.0rpscala35-scala2.9.0
rpscala35-scala2.9.0
 
Reladomo in Scala #scala_ks
Reladomo in Scala #scala_ks Reladomo in Scala #scala_ks
Reladomo in Scala #scala_ks
 
Phantom Type in Scala
Phantom Type in ScalaPhantom Type in Scala
Phantom Type in Scala
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術
 
Javaプログラミング入門【第7回】
Javaプログラミング入門【第7回】Javaプログラミング入門【第7回】
Javaプログラミング入門【第7回】
 
Javaプログラミング入門【第5回】
Javaプログラミング入門【第5回】Javaプログラミング入門【第5回】
Javaプログラミング入門【第5回】
 
null使ったら負け福岡版
null使ったら負け福岡版null使ったら負け福岡版
null使ったら負け福岡版
 
Scala EE 7 Essentials
Scala EE 7 EssentialsScala EE 7 Essentials
Scala EE 7 Essentials
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?
 
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriWhy Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuri
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
 
Java8勉強会
Java8勉強会Java8勉強会
Java8勉強会
 
Shibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R についてShibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R について
 
Scalaノススメ
ScalaノススメScalaノススメ
Scalaノススメ
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門
 

Ähnlich wie Scala勉強会

Scala勉強会_2014_11_18
Scala勉強会_2014_11_18Scala勉強会_2014_11_18
Scala勉強会_2014_11_18Shuya Tsukamoto
 
Java使いにとっての関数
Java使いにとっての関数Java使いにとっての関数
Java使いにとっての関数amkt922
 
scala.collection 再入門 (改)
scala.collection 再入門 (改)scala.collection 再入門 (改)
scala.collection 再入門 (改)Ryuichi ITO
 
Scala再入門 @2014/02/08 Scala関西ビギナーズ第3回
Scala再入門 @2014/02/08 Scala関西ビギナーズ第3回Scala再入門 @2014/02/08 Scala関西ビギナーズ第3回
Scala再入門 @2014/02/08 Scala関西ビギナーズ第3回Asami Abe
 
pi-10. コレクション, ジェネリクス
pi-10. コレクション, ジェネリクスpi-10. コレクション, ジェネリクス
pi-10. コレクション, ジェネリクスkunihikokaneko1
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 
Vim scriptとJavaとHaskell
Vim scriptとJavaとHaskellVim scriptとJavaとHaskell
Vim scriptとJavaとHaskellaiya000
 
Beginners Scala in FAN 20121009
Beginners Scala in FAN 20121009Beginners Scala in FAN 20121009
Beginners Scala in FAN 20121009Taisuke Shiratori
 
RSpecのここがすごい!
RSpecのここがすごい!RSpecのここがすごい!
RSpecのここがすごい!mitim
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!bitter_fox
 
Scalamacrosについて
ScalamacrosについてScalamacrosについて
Scalamacrosについてdekosuke
 
【LT】akka receive とScala Javaの違い
【LT】akka receive とScala Javaの違い 【LT】akka receive とScala Javaの違い
【LT】akka receive とScala Javaの違い 賢太郎 前多
 
Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門だいすけ さとう
 
Equality in Scala (ScalaMatsuri 2020)
Equality in Scala (ScalaMatsuri 2020)Equality in Scala (ScalaMatsuri 2020)
Equality in Scala (ScalaMatsuri 2020)Eugene Yokota
 

Ähnlich wie Scala勉強会 (20)

Javaから使うScala
Javaから使うScalaJavaから使うScala
Javaから使うScala
 
Scala勉強会_2014_11_18
Scala勉強会_2014_11_18Scala勉強会_2014_11_18
Scala勉強会_2014_11_18
 
Java使いにとっての関数
Java使いにとっての関数Java使いにとっての関数
Java使いにとっての関数
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
scala.collection 再入門 (改)
scala.collection 再入門 (改)scala.collection 再入門 (改)
scala.collection 再入門 (改)
 
Scala再入門 @2014/02/08 Scala関西ビギナーズ第3回
Scala再入門 @2014/02/08 Scala関西ビギナーズ第3回Scala再入門 @2014/02/08 Scala関西ビギナーズ第3回
Scala再入門 @2014/02/08 Scala関西ビギナーズ第3回
 
pi-10. コレクション, ジェネリクス
pi-10. コレクション, ジェネリクスpi-10. コレクション, ジェネリクス
pi-10. コレクション, ジェネリクス
 
Scala東北紹介
Scala東北紹介Scala東北紹介
Scala東北紹介
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
Vim scriptとJavaとHaskell
Vim scriptとJavaとHaskellVim scriptとJavaとHaskell
Vim scriptとJavaとHaskell
 
Beginners Scala in FAN 20121009
Beginners Scala in FAN 20121009Beginners Scala in FAN 20121009
Beginners Scala in FAN 20121009
 
RSpecのここがすごい!
RSpecのここがすごい!RSpecのここがすごい!
RSpecのここがすごい!
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!
 
Trait in scala
Trait in scalaTrait in scala
Trait in scala
 
Scalamacrosについて
ScalamacrosについてScalamacrosについて
Scalamacrosについて
 
【LT】akka receive とScala Javaの違い
【LT】akka receive とScala Javaの違い 【LT】akka receive とScala Javaの違い
【LT】akka receive とScala Javaの違い
 
Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門
 
Equality in Scala (ScalaMatsuri 2020)
Equality in Scala (ScalaMatsuri 2020)Equality in Scala (ScalaMatsuri 2020)
Equality in Scala (ScalaMatsuri 2020)
 

Scala勉強会

  • 3. はじめに > 今日はなにをしてくれるのですか? 今日は私が今ハマっているScala を紹介したいと おもいます 需要と 供給
  • 4. はじめに > 対象者? 日常的(?)にJavaが扱える人を対象とします が、私はまだまだScala勉強中ですので、そこらへん のご理解ある方(間違っていても優しくご指摘頂け る方)に限ります
  • 5. はじめに > なぜJavaではなくScalaを? 人と人のつながりを実現している個人的に大好きな Twitter が採用している、Scalaを勉強してみよ うと思った次第です
  • 6. 人類が宇宙に出たことにより出現したのが、ニュータイプです Javaという殻に閉じこもるのではなく、新しい分野を取り入れて、 未来へとつなげて行きたいですね 認めたくないもの だな…、自分自身 の…若さ故の過ち というものを… 人はいつか 時間さえ支 配すること ができるさ はじめに
  • 8. はじめに > では、この勉強会では何をめざしているのですか? Scalaに限らず、Java以外のさまざまなプログラミング言語にも 目を向けて、必要があれば習得し、技術力の底上げを目指す意識 が持てるように、一種の“起爆剤"のような勉強会になれれば良い なと思っています
  • 9. はじめに > みなさんにおかれましては? へえ、あんたもJVMつかってんだ くらいの話半分で楽しんでいただければと!
  • 12. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 13. 第1部:JavaとScala - Scalaって? 特徴その1 スイス連邦工科大学(EPFL) のMartin Odersky先生と いうかたが作った、オブジェクト指向型プログラミ ング言語と関数型プログラミング言語の良い所取り をしたようなプログラミング言語 ※Martin Odersky先生 JavaのGenerics<T>や、Javacを作った方
  • 14. 第1部:JavaとScala - Scalaって? 特徴その2 Javaと同じく、JVM上で動作 コンパイルされるとclassファイルになる つまり、これまで作られてきたJavaプロダクトのす べてをScalaから使うことができる もちろん、classファイルになるのでJava側からも Scalaプロダクトを使うことができる
  • 15. 第1部:JavaとScala - Scalaって? 特徴その3 その他もろもろある のですが、割愛
  • 16. 第1部:JavaとScala - Scalaって? 特徴その4(個人的に思う最大の特徴) コレクションのライブラリがちょーーー強力 後ほどご紹介
  • 17. 第1部:JavaとScala - Scalaって? 特徴その5(個人的に思う特徴) 書いてて楽しい Java Scala ← 体感→ ※どっちも楽しい
  • 18. 第1部:JavaとScala - Scalaって? 特徴その6(個人的に思う特徴) 最新プログラミング言語SwiftがScalaに似ている Scalaやってるので割とスラスラ読めた
  • 19. 第1部:JavaとScala - Scalaって? 特徴その-1(Scalaのあまり良くないところ) Date関連のAPIがない →あるかもしれないけど、みんなJavaのDateをよく 使っている def nowDate: java.util.Date = new java.util.Date
  • 20. 第1部:JavaとScala - Scalaって? 特徴その-2(Scalaのあまり良くないところ) とにかく学習コストが高い →私は今のところ半年強くらいやってるけど まだスラスラ書けず(それは私がカスだかr
  • 21. 第1部:JavaとScala - Scalaって? 特徴その-3(Scalaのあまり良くないところ) コンパイルがクソ遅い 頻繁に取り上げられるが、一部ではそのゲロ遅さが カワイイとの声も しかしsbtというのがあって...
  • 22. 第1部:JavaとScala - Scalaって? 特徴その-4(Scalaのあまり良くないところ) 仕事が無い SI業やってるうちはScalaなんてやらない方が良い 脱SI目指すなら、ScalaでなくSwiftの方が良いんじゃないか とか思ってたり
  • 23. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 24. 第1部:JavaとScala - REPL コマンドラインでScalaプログラムを実行できる機能 Scalaをインストールすれば使うことができる ちょっとした動作確認をするときなど便利 $ scala Welcome to Scala version 2.10.3 (Java HotSpot(TM) Client VM, Java 1.7.0_55). Type in expressions to have them evaluated. Type :help for more information. scala> 1 + 1 res0: Int = 2 scala>_
  • 25. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 26. 第1部:JavaとScala - 変数宣言 おなじみ String name = "シャア・アズナブル"; final String name = "アムロ・レイ"; Java
  • 27. Scala 第1部:JavaとScala - 変数宣言 varとvalがある var name: String = "シャア・アズナブル" val name: String = "アムロ・レイ" varはvariable(変数)という意味で再代入が可能 valはvalue(値)という意味で再代入が不可能
  • 28. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 29. 第1部:JavaとScala - 制御構文 おなじみ if (true/false) {} else {} for (String val : list) {} Java
  • 30. Scala 第1部:JavaとScala - 制御構文 Javaに良く似ている if (true/false) {} else {} for (val <- list) {} もちろん、while文やdo~whileもあるけど割愛
  • 31. Scala 第1部:JavaとScala - 制御構文 for文の中にif文を書く事が出来る val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") for (name <- nameList if !name.isEmpty) { println(name) }
  • 32. Scala 第1部:JavaとScala - 制御構文 yieldを使うことで、処理結果をコレクションと して受け取る事が出来る val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") val resultList: List[String] = for (name <- nameList if !name.isEmpty) yield { name } println(resultList)
  • 33. Java 第1部:JavaとScala - 制御構文 Javaでやろうとするとこんな感じ List<String> nameList = Arrays.asList("シャア・アズナブル","","アムロ・レイ"); List<String> resultList = new ArrayList<String>(); for (String name : nameList) { if (name.isEmpty()) continue; resultList.add(name); } System.out.println(resultList);
  • 34. 第1部:JavaとScala - 制御構文 for文のネストについて 例えば、リストの中にリストが入る構造のデータが あったとする firstList secondList secondList ガンダム ジム ガンタンク ザクII グフ ジオング
  • 35. Java 第1部:JavaとScala - 制御構文 Javaで初期化するとこう List<List<String>> firstList = Arrays.asList( Arrays.asList("ガンダム","ジム","ガンタンク") ,Arrays.asList("ザクII","グフ","ジオング") );
  • 36. Scala 第1部:JavaとScala - 制御構文 Scalaで初期化するとこう val firstList: List[List[String]] = List( List("ガンダム","ジム","ガンタンク") ,List("ザクII","グフ","ジオング") )
  • 37. Java 第1部:JavaとScala - 制御構文 ネストforループのしかた Javaではおなじみ for (List<String> secondList : firstList) { for (String name : secondList) { System.out.println(name); } }
  • 38. Scala 第1部:JavaとScala - 制御構文 ネストforループのしかた セミコロンで区切って簡潔に記述可能 for (secondList <- firstList ; name <- secondList) { println(name) }
  • 39. 第1部:JavaとScala - 制御構文 パターンマッチについて(match~case) Javaのswitch~caseに似ているが、Scalaの match~caseは、主力といっても良いほどちょー強力 な機能
  • 40. Java 第1部:JavaとScala - 制御構文 Javaのswitch~caseで書いた例 String name = "シャア・アズナブル"; switch (name) { case "シャア・アズナブル": System.out.println("ジオン公国軍"); break; case "アムロ・レイ": System.out.println("地球連邦軍"); break; default: System.out.println("民間人"); break; }
  • 41. Scala 第1部:JavaとScala - 制御構文 Scalaのmatch~caseだとこう あまり変わりないけど... val name: String = "シャア・アズナブル" name match { case "シャア・アズナブル" => println("ジオン公国軍") case "アムロ・レイ" => println("地球連邦軍") case _ => println("民間人") }
  • 42. Scalaのmatch~caseは型でもパターンマッチ出来た り... abstract class MS(val name: String) class NewGundam(override val name: String) extends MS(name) class Sazaby(override val name: String) extends MS(name) class Unicorn(override val name: String) extends MS(name) def matcher(ms: MS) = ms match { case mss: NewGundam => println(mss.name + " by ニューガンダム") case mss: Sazaby => println(mss.name + " by サザビー") case _ => println("所属不明機") } Scala 第1部:JavaとScala - 制御構文
  • 43. Scala 第1部:JavaとScala - 制御構文 他にも柔軟なパターンマッチを実現することができ たり List.range(1, 10) foreach { i => (i % 3, i % 5) match { case (0, 0) => println("FizzBuzz") case (0, _) => println("Fizz") case (_, 0) => println("Buzz") case _ => println(i) } }
  • 44. 第1部:JavaとScala - コレクションライブラリ mapとforeachの紹介 Q.forループ処理ってなんのために使う? Scala
  • 45. Scala 第1部:JavaとScala - コレクションライブラリ mapとforeachの紹介 A.基本的にコレクションに対する値の操作
  • 46. Scala 第1部:JavaとScala - コレクションライブラリ mapとforeachの紹介 A.基本的にコレクションに対する値の操作 さて、冒頭で「Scalaのコレクションにはちょー強力なライブラ リが多い」と述べたとおり 実は、それらを利用すると、for文自体使わなくても良いケースが 多かったりする
  • 47. Scala 第1部:JavaとScala - コレクションライブラリ foreach 例えば先ほどの下記は val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") for (name: String <- nameList if !name.isEmpty) { println(name) }
  • 48. Scala 第1部:JavaとScala - コレクションライブラリ この様に記述できる val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") nameList.filter(x => !x.isEmpty).foreach { println(_) } 省略できる nameList.filter(x => !x.isEmpty) foreach(println(_)) さらに省略できる(やりすぎると意味不明に...) nameList.filter(x => !x.isEmpty) foreach println
  • 49. Scala 第1部:JavaとScala - コレクションライブラリ 他にもいろいろなライブラリ この場合は val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") val resultList: List[String] = for (name: String <- nameList if !name.isEmpty) yield { name } filterメソッドを使えば一発 val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") val resultList: List[String] = nameList.filter(x => !x.isEmpty)
  • 50. Scala 第1部:JavaとScala - コレクションライブラリ map mapメソッドを使うと、より柔軟かつ簡潔な記述が 出来る val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") val resultList:List[String] = nameList.filter(x => !x.isEmpty) map { name => name.replace("シャア・アズナブル","キャスバル・レム・ダイクン") } println(resultList)
  • 51. Scala 第1部:JavaとScala - コレクションライブラリ foreachとmapの使い分け どちらも要素に対して順次操作するが ・foreachはループ処理内だけで処理を完結 ・mapはループ処理から戻り値を取得 する使い分けとなるとのこと
  • 52. Scala 第1部:JavaとScala - コレクションライブラリ foreach 要素による処理を実行 nameList.filter(x => !x.isEmpty) foreach { name => println(name) }
  • 53. Scala 第1部:JavaとScala - コレクションライブラリ map 要素に変更を加える処理を実行 ただし、Scalaでは副作用を引き起こす“要素そのものに変更を加える”事を良しとしないので、新しいコレクショ ンを生成する val resultList:List[String] = nameList.filter(x => !x.isEmpty) map { name => name.replace("シャア・アズナブル","キャスバル・レム・ダイクン") }
  • 54. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 55. 第1部:JavaとScala - Tuple Scala Tuple Tuple(タプル)とは、複数のさまざまな型のデータ を一つにまとめる事が出来る機能 さまざまなシーンで使える ただし、格納出来るオブジェクトは22個まで(タプ ル23問題)
  • 56. Scala 第1部:JavaとScala - Tuple Tuple メソッドの戻り値を例に見てみる
  • 57. 第1部:JavaとScala - Tuple Javaのメソッドの戻り値は一つ public String getFirstName() { return this.firstName; } public String getLastName() { return this.lastName; } public int getAge() { return this.age; } public String getFullName() { return this.firstName + this.lastName; } Java
  • 58. Scala 第1部:JavaとScala - Tuple メソッドの戻り値にTupleを使えば... case class Employee(val firstName: String, val lastName: String, val age: Int) { def allData = (firstName, lastName, age) // Tupleを返却する } val emp: Employee = Employee("kazuomi","Endo",31) val allData = emp.allData println(allData._1) // kazuomi println(allData._2) // endo println(allData._3) // 31 println(allData._4) // これはコンパイルエラー
  • 59. Scala 第1部:JavaとScala - Tuple Tuple さまざまなシーンで使える ただし、格納出来るオブジェクトは22個まで(タプ ル23問題)
  • 60. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 61. 第1部:JavaとScala - 無名関数Scala 無名関数 先ほど説明したコレクションの所で、下記の様な見 慣れない書き方があった nameList.filter(x => !x.isEmpty)
  • 62. Scala 第1部:JavaとScala - 無名関数 無名関数 これはJavaで言う無名クラスの様なもので、省略せ ずに書くとこうなる nameList.filter { (x: String) => { !x.isEmpty } }
  • 63. Scala 第1部:JavaとScala - 無名関数 無名関数 ここら辺が無名関数 nameList.filter { (x: String) => { !x.isEmpty } }
  • 64. Scala 第1部:JavaとScala - 無名関数 無名関数 ワンライナーの場合は省略した方が読みやすくなっ たり、ならんかったり nameList.filter(x => !x.isEmpty)
  • 65. Scala 第1部:JavaとScala - 無名関数 無名関数 ちなみに、コレクションで説明した例の記述をあえ てJavaで書くと val nameList: List[String] = List("シャア・アズナブル","","アムロ・レイ") val filteredList: List[String] = nameList.filter(x => !x.isEmpty) println(filteredList)
  • 66. Java 第1部:JavaとScala - 無名関数 無名クラス interface MyList { public List<String> filter(List<String> nameList); } MyList filterList = new MyList() { public List<String> filter(List<String> nameList) { List<String> returnList = new ArrayList<String>(); for (String name : nameList) { if (name != null && name != ””) { returnList.add(name); } } return returnList; } };
  • 67. Java 第1部:JavaとScala - 無名関数 ここらへんが無名クラス interface MyList { public List<String> filter(List<String> nameList); } MyList filterList = new MyList() { public List<String> filter(List<String> nameList) { List<String> returnList = new ArrayList<String>(); for (String name : nameList) { if (name != null && name != ””) { returnList.add(name); } } return returnList; } };
  • 68. Java 第1部:JavaとScala - 無名関数 実行 List<String> nameList = Arrays.asList("シャア・アズナブル","","アムロ・レイ"); List<String> filteredList = filterList.filter(nameList); System.out.println(filteredList);
  • 69. Java 第1部:JavaとScala - 無名関数 まあ、Listの要素をフィルターするだけに普通こん なことはしないけど、無名関数の参考程度までに
  • 70. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 71. 第1部:JavaとScala - クラスとオブジェクト クラスの定義 まあおなじみでしょうか class MyClass { } Java
  • 72. 第1部:JavaとScala - クラスとオブジェクト クラスの定義 ほとんどJavaと同様 class MyClass { } Scala
  • 73. 第1部:JavaとScala - クラスとオブジェクト クラスの定義 コンストラクタ class MyClass { public MyClass() { System.out.println("Hello World!"); } } Java
  • 74. 第1部:JavaとScala - クラスとオブジェクト クラスの定義 コンストラクタはJavaで言うメンバに定義する class MyClass { // ここにコンストラクタの処理を定義 println("Hello World!") } Scala
  • 75. 第1部:JavaとScala - クラスとオブジェクト クラスの定義 引数ありのコンストラクタ class MyClass { public MyClass(String name) { } } Java
  • 76. 第1部:JavaとScala - クラスとオブジェクト クラスの定義 Scalaの場合、クラスの定義に引数を記述 class MyClass(name: String) { // ここにコンストラクタの処理を定義 println("Hello World! %s".format(name)) } --- val nameC = new MyClass("アムロ!") Hello World! アムロ! nameC: MyClass = MyClass@1835d850 Scala
  • 77. 第1部:JavaとScala - クラスとオブジェクト クラスの定義 二つ以上のコンストラクタ(オーバーロード) class MyClass { public MyClass(String name) { } public MyClass(String name, int age) { } } Java
  • 78. 第1部:JavaとScala - クラスとオブジェクト クラスの定義 Scalaでは2つめ以降のコンストラクタを「補助コンストラク タ」と言い、その前に定義されたコンストラクタを呼び出す必要 がある class MyClass(name: String) { println("Hello World! %s".format(name)) // 補助コンストラクタ def this(name: String, age: Int) = { this(name) println("Hello World! %s %d".format(name, age)) } } Scala
  • 79. 第1部:JavaとScala - クラスとオブジェクト Scala オブジェクトの定義 Scalaにはstaticの概念は無いが、シングルトンオブ ジェクト(アプリ内に1つしかないオブジェクト) を定義する事が出来る object MyObject { val limit = 1000 }
  • 80. Scala 第1部:JavaとScala - クラスとオブジェクト コンパニオンオブジェクトの定義 同名のクラスとオブジェクトを同一ソースに定義す ると、そのオブジェクトはコンパニオンオブジェク トと呼ばれるものになり、オブジェクトとクラス間 でprivateメンバへのアクセスが可能となる 主にクラスを生成する役目として利用する(ファク トリー)
  • 81. 第1部:JavaとScala - クラスとオブジェクト コンパニオンオブジェクトの定義 class MyName(name: String) { println("Hello World! %s".format(name)) } object MyName { // applyの定義が必要 def apply(name: String) = new MyName(name) } MyName.apply("Name") // Hello World! TEST MyName("Name") // applyは少し特殊で、省略可能 Scala
  • 82. 第1部:JavaとScala - クラスとオブジェクト Scala ケースクラスの定義 いくつかの便利なメソッドやコンパニオンオブジェ クトが自動的に生成される コンストラクタに対するパターンマッチが利用出来 たり、値を保持するDTOとしての定義に利用 case class MyClass(name: String) { println("Hello World! %s".format(name)) }
  • 83. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 84. 第1部:JavaとScala - Option型Scala Option型 値があるかないかを表す箱の様なもの nullの可能性がある変数を、Option型でラップをする ことにより、より安全なプログラミングを実現する 仕組み モナドという概念を使うときにも必要?
  • 85. Scala 第1部:JavaとScala - Option型 Option型 Option型のサブクラスには ● Some型:値がある場合 ● None型:値がない場合 がある
  • 86. Scala 第1部:JavaとScala - Option型 Option型 まだうまく説明できず(笑) なので、Mapを使ってニュアンスだけで...
  • 87. Java 第1部:JavaとScala - Option型 Mapを使った例 下記はコンパイルエラーにならず、実行してもエラ ーにはならない final Map<String, String> pilotMap = new HashMap<String, String>() {{ put("1", "ガンダム"); put("2", null); }}; System.out.println(pilotMap.get("1").length());
  • 88. Java 第1部:JavaとScala - Option型 Mapを使った例 しかし、key:2を指定すると、実行時にヌルポが発 生する(当たり前) final Map<String, String> pilotMap = new HashMap<String, String>() {{ put("1", "ガンダム"); put("2", null); }}; System.out.println(pilotMap.get("2").length());
  • 89. Java 第1部:JavaとScala - Option型 Mapを使った例 しかし、key:3を指定しても、実行時にヌルポが発 生する(当たり前) final Map<String, String> pilotMap = new HashMap<String, String>() {{ put("1", "ガンダム"); put("2", null); }}; System.out.println(pilotMap.get("3").length());
  • 90. Java 第1部:JavaとScala - Option型 Mapを使った例 さて、key:2とkey:3指定した時、どちらも実行時に ヌルポで落ちたが ● 値がなくてヌルポが発生したのか ● keyがなくてヌルポが発生したのか 一見どちらが原因でエラーとなったのか不明
  • 91. Java 第1部:JavaとScala - Option型 Mapを使った例 対応するとしたら下記の様な対応か? ・keyの存在チェック ・nullチェックする しかし、そもそもコンパイラは、これらの対応がさ れているか分からない
  • 92. Java 第1部:JavaとScala - Option型 Mapを使った例 final Map<String, String> pilotMap = new HashMap<String, String>() {{ put("1", "ガンダム"); put("2", null); }}; if (pilotMap.containsKey("1") && pilotMap.get("1") != null) System.out.println(pilotMap.get("1").length()); if (pilotMap.containsKey("2") && pilotMap.get("2") != null) System.out.println(pilotMap.get("2").length()); if (pilotMap.containsKey("3") && pilotMap.get("3") != null) System.out.println(pilotMap.get("3").length());
  • 93. Scala 第1部:JavaとScala - Option型 Mapを使った例 こうしたコンパイルチェック時に検出できない潜在 バグを極力なくしていくのが、ScalaのOption型(だ と思っている) では実際にどうやって先ほどの問題を解決するのか
  • 94. Scala 第1部:JavaとScala - Option型 Mapを使った例 そこでパターンマッチ(match~case)を使う Option型は、値が存在する場合はSome型、値が存 在しない場合None型を返すため、パターンマッチで それらを検出する
  • 95. Scala 第1部:JavaとScala - Option型 Mapを使った例 val pilotMap: Map[String, String] = Map("1" -> "ガンダム", "2" -> null) def checkValue(key: String) = pilotMap.get(key) match { case Some(v) if v == null => "nullです" case Some(v) => "%sです" format v case None => "値はありません" } println(checkValue("1")) // ガンダムです println(checkValue("2")) // nullです println(checkValue("3")) // 値はありません
  • 96. Scala 第1部:JavaとScala - Option型 Mapを使った例 値にnullが入るのは仕方のないことなので、やはり nullチェックは必要 しかし、Mapのkeyが存在しない場合については、 Noneが帰ってくるため、明示的な実装が可能になる
  • 97. Scala 第1部:JavaとScala - Option型 Mapを使った例 もちろん、Javaでもkeyと値が存在するかどうかの チェックメソッドを一つ作れば良い話だけど、標準 で安全なプログラミングをサポートしているという 感じが良い
  • 98. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 99. 第1部:JavaとScala - 引数について(+部分適用とカリー化) 引数について- 通常 def f(arg1: String,arg2: String): String = { "%sと%s".format(arg1,arg2) } println(f("引数①","引数②")) ---実行結果--- 引数①と引数② Scala
  • 100. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 引数について- 変数名指定 def f(arg1: String,arg2: String): String = { "%sと%s".format(arg1,arg2) } println(f(arg1 = "引数①",arg2 = "引数②")) ---実行結果--- 引数①と引数②
  • 101. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 引数について- 可変長引数 def f(args: String*) = args foreach println f("引数①","引数②") ---実行結果--- 引数① 引数②
  • 102. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 引数について- 可変長引数 引数が可変長引数の場合、コレクションも渡すこと ができる(ただし、_*をつける必要あり) def f(args: String*) = args foreach println f(List("引数①","引数②"): _*) ---実行結果--- {同じ}
  • 103. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 引数について- 初期値 def f(arg1: String,arg2: String = "引数②"): String = { "%sと%s".format(arg1,arg2) } println(f("引数①")) ---実行結果--- 引数①と引数②
  • 104. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 引数について- 初期値 これはコンパイラがどの引数に入れたら良いのか分 からないので、コンパイルエラーとなる def f(arg1: String = "引数①",arg2: String): String = { "%sと%s".format(arg1,arg2) } println(f("引数②"))
  • 105. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 引数について- 初期値 変数名指定すればOK def f(arg1: String = "引数①",arg2: String): String = { "%sと%s".format(arg1,arg2) } println(f(arg2 = "引数②")) ---実行結果--- 引数①と引数②
  • 106. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 引数について- 初期値 指定した値を優先する def f(arg1: String = "引数①",arg2: String): String = { "%sと%s".format(arg1,arg2) } println(f(arg1 = "引数③",arg2 = "引数②")) ---実行結果--- 引数③と引数②
  • 107. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 部分適用 メソッドの引数の一部を固定し、新たに関数オブジ ェクト(変数)を生成できるしくみ
  • 108. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) 部分適用 def f1(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) val f2 = f1("引数①", _:String) // 引数1を固定して関数オブジェクトを作成 println(f2("引数②")) val f3 = f1(_:String, "引数②") // 引数2を固定して関数オブジェクトを作成 println(f3("引数①")) ---実行結果--- 引数①と引数② 引数①と引数②
  • 109. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) カリー化 メソッドの引数を分け、第1引数から順次受け取る メソッドを新たに定義出来るしくみ
  • 110. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) カリー化 // メソッドを定義 def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) ※当該メソッドの処理内容 methodは二つの引数を取り、それぞれの値を"%sと%s"にバインドStringInterpolationし、 String型として返します。
  • 111. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) カリー化 // メソッドを定義 def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) val functionObject = method _ // メソッドを関数オブジェクト化
  • 112. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) カリー化 // メソッドを定義 def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) val functionObject = method _ // メソッドを関数オブジェクト化 val curreidFunction = functionObject.curried // 関数オブジェクトをカリー化
  • 113. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) カリー化 // メソッドを定義 def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) val functionObject = method _ // メソッドを関数オブジェクト化 val curreidFunction = functionObject.curried // 関数オブジェクトをカリー化 // 第1引数を指定し、第2引数を引数として受け取る関数オブジェクトを作成 val function1 = curreidFunction("引数①")
  • 114. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) カリー化 // メソッドを定義 def method(arg1: String, arg2: String): String = "%sと%s".format(arg1, arg2) val functionObject = method _ // メソッドを関数オブジェクト化 val curreidFunction = functionObject.curried // 関数オブジェクトをカリー化 // 第1引数を指定し、第2引数を引数として受け取る関数オブジェクトを作成 val function1 = curreidFunction("引数①") println(function1("引数②-1")) // 第2引数を指定して処理を実行 ---実行結果--- 引数①と引数②-1
  • 115. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) カリー化 初めからカリー化されたメソッドを定義した場合 // メソッドを定義 def method(arg1: String) = (arg2: String) => "%sと%s".format(arg1, arg2) // 第1引数を指定し、第2引数を引数として受け取る関数オブジェクトを作成 val function1 = method("引数①") println(function1("引数②-1")) // 第2引数を指定して処理を実行 ---実行結果--- 引数①と引数②-1
  • 116. Scala 第1部:JavaとScala - 引数について(+部分適用とカリー化) カリー化 いっぺんに実行することも可能 // メソッドを定義 def method(arg1: String) = (arg2: String) => "%sと%s".format(arg1, arg2) println(method("引数①")("引数②-1")) ---実行結果--- 引数①と引数②-1
  • 117. 第1部:JavaとScala ● Scalaって? ● REPL ● 変数宣言 ● 制御構文/コレクションのライブラリ ● Tuple ● 無名関数 ● クラスとオブジェクト ● Option型 ● 引数について(+部分適用とカリー化) ● クロージャ
  • 118. 第1部:JavaとScala - クロージャScala クロージャ まずは静的スコープのお話 ブロックAの変数xとブロックBの変数xは同じ名前をもつがブロックが異なる為別のも のである。またBの中ではCのようにさらに内側の変数を見ることができず、逆にCから はBのxとCのyが見える※Wikipediaから引用 A {var x} // A内のみ参照可能 B { var x // BとCから参照可能で、A内のxとは別物 C {var y} // C内のみ参照可能 }
  • 119. Scala 第1部:JavaとScala - クロージャ クロージャ よくある例 var count = 100 def counter() = { var count = 200 () => { count += 10 count } } val c1 = counter() println(c1()) println(c1())
  • 120. Scala 第1部:JavaとScala - クロージャ クロージャ この場合、無名関数()が参照するcountは、直近スコ ープにある200で初期化されたものが利用される var count = 100 def counter() = { var count = 200 () => { count += 10 count } }
  • 124. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 125. 第2部:Play Framework Play Frameworkって? JavaとScalaどちらでも実装出来るWebアプリケー ションフレームワーク ・MVC ・ホットリローディングあり ・ステートレス(セッション無し)
  • 126. 第2部:Play Framework Play Frameworkって? 1.X系と2.X系で、まったくの別物 2014/07現在は2.3が最新
  • 127. 第2部:Play Framework Play Frameworkって? 実はただのsbt
  • 128. 第2部:Play Framework Play Frameworkって? Nettyサーバーが組み込まれており、それを使って実 行するように設計されている けど Warに固めてデプロイもできる(非推奨?)
  • 129. 第2部:Play Framework Play Frameworkって?
  • 130. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 131. Scala Java 第2部:Play Framework インストール 2.2まではPlayのzipをダウンロードして、$PATHに 通すだけで良かった 2.3からは下記サイトからActivatorを取得し、$PATH に追加するか、「brew install typesafe-sctivator」す る Playframework http://www.playframework.com/
  • 132. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 133. Scala Java 第2部:Play Framework プロジェクトの作成、起動 まずは「activator new」コマンドを実行する $ activator new ~割愛~
  • 134. Java 第2部:Play Framework プロジェクトの作成、起動 作成するプロジェクトの形式を選択する 例ではScalaを選択 Scala ~割愛~ Choose from these featured templates or enter a template name: 1) minimal-java 2) minimal-scala 3) play-java 4) play-scala (hit tab to see a list of all templates) > 4
  • 135. 第2部:Play Framework プロジェクトの作成、起動 アプリケーション名を入力する 例では「My App」を入力 Scala Java ~割愛~ Enter a name for your application (just press enter for 'play-scala') > MyApp OK, application "MyApp" is being created using the "play-scala" template. ~割愛~
  • 136. Scala Java 第2部:Play Framework プロジェクトの作成、起動 作成された「My App」ディレクトリに移動し 「activator run」コマンドを実行して移動 $ cd MyApp/ $ activator run ~割愛~ [info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
  • 137. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 138. Scala Java 第2部:Play Framework リクエスト→レスポンスの流れ まず初めに、トップ画面のリクエストを行う http://localhost:9000/
  • 139. Scala Java 第2部:Play Framework リクエスト→レスポンスの流れ すると、「conf/routes」ファイルに記載されている下記の内容を もとに、呼び出す処理を解決する GET / controllers.Application.index → app/controllers/Application.java → app/controllers/Application.scala のindexメソッド
  • 140. Java 第2部:Play Framework リクエスト→レスポンスの流れ JavaのControllerはこのような記述 public static Result index() { Ok(index.render("Hello World!")); }
  • 141. Scala 第2部:Play Framework リクエスト→レスポンスの流れ ScalaのContrllerはこの様な記述 def index() = Action { implicit request => Ok(html.index("Hello World!")) }
  • 142. Scala Java 第2部:Play Framework リクエスト→レスポンスの流れ 次に、Okメソッドに指定したページをレスポンスと して返す app/views/index.scala.html
  • 143. Scala Java 第2部:Play Framework app/views/index.scala.html 画面の定義はJavaとScalaほぼ同じ @(text: String) @main("indexページ") { <p>@text</p> }
  • 144. Scala Java 第2部:Play Framework app/views/index.scala.html @はじまりの箇所はすべてScalaのロジック @(text: String) @main("indexページ") { <p>@text</p> }
  • 145. Scala Java 第2部:Play Framework app/views/index.scala.html さらにここからmainと定義されたページテンプレー トを呼び出す @main("indexページ") {} → app/views/main.scala.html
  • 146. Scala Java 第2部:Play Framework リクエスト→レスポンスの流れ app/views/main.scala.html contentに先述のindexページが格納されている @(title: String)(content: Html) <html> <head> <title>@title</title> </head> <body> @content </body> </html>
  • 147. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 148. Scala Java 第2部:Play Framework ルーティング リクエストパラメータは下記の様に指定する View <a href="@routes.Application.index(1)">トップ</a> conf/routes GET / controllers.Application.index(p: Int)
  • 149. Java 第2部:Play Framework ルーティング リクエストパラメータは下記の様に指定する Controller public static Result index(int p) { Ok(index.render("Hello World!")); }
  • 150. Scala 第2部:Play Framework ルーティング リクエストパラメータは下記の様に指定する Controller def index(p: Int) = Action { implicit request => Ok(html.index("Hello World!")) }
  • 151. Scala Java 第2部:Play Framework ルーティング 下記の様に記述することで、初期値を指定でき る conf/routes GET / controllers.Application.index(p: Int ?= 1)
  • 152. Scala Java 第2部:Play Framework ルーティング 下記の様に記述することで、リクエストパラメータ をURLの一部に指定できる conf/routes GET /:p controllers.Application.index(p: Int) URL http://localhost:9000/1
  • 153. Scala Java 第2部:Play Framework ルーティング リバースルーティングも可能(初期指定済み) conf/routes GET /assets/*file controllers.Assets.at(path="/public", file) View <script type="text/javascript" src="@routes.Assets.at("javascripts/bootstrap.min.js")"></script>
  • 154. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 155. Scala Java 第2部:Play Framework Database接続設定 Database接続を行うには、下記ファイルにエンドポ イントを記述する conf/application.conf
  • 156. Scala Java 第2部:Play Framework Database接続設定 PlayにはH2が組み込まれており、下記の記述を有効 化するだけで利用できる db.default.driver=org.h2.Driver db.default.url="jdbc:h2:mem:play" db.default.user=sa db.default.password=""
  • 157. Scala Java 第2部:Play Framework Database接続設定 MySQLを利用する場合 下記の様にエンドポイントを記述し... db.default.driver=com.mysql.jdbc.Driver db.default.url="jdbc:mysql://localhost:3306/{DATABASE_NAME} db.default.user={USER_NAME} db.default.password="{PASS_WORD}"
  • 158. Scala Java 第2部:Play Framework Database接続設定 MySQLを利用する場合 Configuration Fileに下記の様な記述を行う build.sbt val appDependencies = Seq( // Add your project dependencies here, "mysql" % "mysql-connector-java" % "5.1.20" )
  • 159. Scala Java 第2部:Play Framework Database接続設定 Configuration Fileはsbt※のものなので詳細は割愛 ※簡単に言うと、必要なライブラリを管理出来るビ ルドツール
  • 160. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 161. Scala Java 第2部:Play Framework Revolution機能 play runすると、 conf¥evolutions¥default¥1.sql というファイルに定義されたSQLを実行してくれる。 開発中のDB定義マイグレーションに便利。
  • 162. Scala Java 第2部:Play Framework Evolution機能 http://localhost:9000/ にアクセスすると、下記 の様にDBを構築するスクリプトが表示される ので、「Apply this script now!」を押下する。 ※スクリプトはdefault¥1.sqlの中身。
  • 163. Scala Java 第2部:Play Framework Evolution機能
  • 164. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 165. Scala Java 第2部:Play Framework DB操作 親テーブル(1)と子テーブル(N)という2つのテ ーブルが存在するデータベースがあったとする。 各テーブルからデータを登録・読取・更新・削 除する場合の実装方法例を記載する。
  • 166. Java 第2部:Play Framework DB操作 Java版では、Ebeanを利用(Playに同梱済み)。 conf/application.conf に ebean.default="models.*" を記述してモデルクラス格納パッケージを指定する。 Ebean http://www.avaje.org/ebean/documentation.html
  • 167. Java 第2部:Play Framework DB操作 app/models パッケージに、親テーブルと子テーブル用の 「@Entity」「extends Model」 を適用したモデルクラスを作成する。
  • 168. Java 第2部:Play Framework DB操作- 親テーブル定義例 @Entity public class Parent extends Model { private static final long serialVersionUID = 1L; @Id public Long id; @Required public String name; @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent") public List<Child> child = new ArrayList<Child>(); protected Timestamp createDate; @Version protected Timestamp updateDate; public static Finder<Long,Parent> find = new Finder<Long,Parent>(Long.class, Parent.class); }
  • 169. Java 第2部:Play Framework DB操作- 子テーブル定義例 @Entity public class Child extends Model { private static final long serialVersionUID = 1L; @Id public Long id; @Required public String name; @ManyToOne @JoinColumn(name = "child") public Parent parent; protected Timestamp createDate; @Version protected Timestamp updateDate; public static Finder<Long,Child> find = new Finder<Long,Child>(Long.class, Child.class); }
  • 170. Java 第2部:Play Framework DB操作 play runすると、 conf¥evolutions¥default¥1.sql を作成してくれる。 Ebeanの良いところ。
  • 171. Java 第2部:Play Framework DB操作 実際のデータ取得は、先のモデルクラスに定義した public static Finder<Long,Parent> find = new Finder<Long,Parent>(Long.class, Parent.class); を使用する。
  • 172. Java 第2部:Play Framework DB操作 データ取得例 List<Parent> parentList = Parent.find.findList(); List<Parent> parentList = Parent.find.where().eq(“name”, “omiend").findList(); List<Parent> parentList = Parent.find.setFirstRow(0).setMaxRows(10).findList(); int rowCount = Parent.find.findRowCount();
  • 173. 第2部:Play Framework Scala DB操作 Scala版ではScalaikeJDBCがトレンドだが、私は勉 強中なので、今回は実際に使ったAnormを紹介
  • 174. 第2部:Play Framework DB操作 Configuration Fileに下記の様な記述を行う build.sbt val appDependencies = Seq( // Add your project dependencies here, anorm ) Scala
  • 175. 第2部:Play Framework DB操作 モデルクラスを用意する 下記は先述のケースクラスとオブジェクト(コンパニオンオブジェクト)を一緒に ParentModel.scalaに定義した例 DDLはオブジェクト内に定義して行く事となる case class Parent(id: Pk[Long] = NotAssigned ,name: String ,var createDate: Option[Date] ,var updateDate: Option[Date]) { } object Parent { } Scala
  • 176. 第2部:Play Framework Scala DB操作 取得したデータをモデルにマッピングする為の定義 をする object Parent { val simple = { get[Pk[Long]]("parent.id") ~ get[String]("parent.name") ~ get[Date]("parent.create_date") ~ get[Date]("parent.update_date") map { case id~name~createDate~updateDate => Parent(id, name, Option(createDate), Option(updateDate)) } } }
  • 177. 第2部:Play Framework DB操作 DDLを定義する object Parent { def findByName(name: String): Seq[Parent] = { DB.withConnection { implicit connection => SQL(""" select * from parent where name = {name} """).on( 'name -> name ).as(Parent.simple *) }}} Scala
  • 178. 第2部:Play Framework DB操作 データ取得例 val resultList = Parent.findByName(“omiend") Scala
  • 179. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 180. Java 第2部:Play Framework Formの定義 Javaの場合、下記の様にモデルクラスを利用して Formを作成する Form<Parent> parentForm = form(Parent.class); return ok(create.render(parentForm));
  • 181. 第2部:Play Framework Formの定義 Scalaの場合、下記の様なモデルへのマッピングオブ ジェクトを作成する val parentForm = Form( mapping( "id" -> ignored(NotAssigned: Pk[Long]), "name" -> nonEmptyText, "createDate" -> optional(date("yyyy-MM-dd")), "updateDate" -> optional(date("yyyy-MM-dd")) )(Parent.apply)(Parent.unapply) ) Ok(html.create(parentForm)) Scala
  • 182. Scala Java 第2部:Play Framework Formの定義- Viewの定義例 @(parentForm: Form[Parent]) @import helper._ @main() { @form(routes.Application.insertParent()) { <fieldset> @inputText(parentForm("name")) </fieldset> <div class="actions"> <input type="submit" value="登録"> or <a href="@routes.Application.index()" class="btn">Cancel</a> </div> } }
  • 183. Scala Java 第2部:Play Framework Formの定義- Viewの定義例
  • 184. Scala Java 第2部:Play Framework Formの定義- Viewの定義例 POST先のroutes設定はこんな感じ conf/routes POST /insertParent controller.Application.insertParent
  • 185. 第2部:Play Framework ● Play Frameworkって? ● インストール ● プロジェクトの作成・起動 ● リクエスト→レスポンスの流れ ● ルーティング ● Database接続設定 ● Evolution機能 ● DB操作 ● Formの定義 ● まとめ(JavaとScala比べ)
  • 186. Scala Java 第2部:Play Framework まとめ(Java版とScala版比べ) ● Viewの定義方法はどちらも同じ ● EbeanとAnormでは、Ebeanの方が実装が容易 ● Formの定義もJava版の方が容易 ● Java版でも、Javaでの実装はControllerとModelだ けで、他はすべてScalaで実装する必要がある ● ビルドはScalaのsbtが利用されるので、その辺の 知識は必須