Ipros techmeetup 20131218_scala_handson

2,234 views
2,135 views

Published on

2013/12/18に株式会社イプロスにて開催されたScalaハンズオン勉強会の後半パートで使用したスライドです。

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,234
On SlideShare
0
From Embeds
0
Number of Embeds
1,752
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Ipros techmeetup 20131218_scala_handson

  1. 1. 未経験者のためのScala 株式会社イプロス 本多陽平
  2. 2. 後半パート Scalaの真髄に少しだけ触れる 2 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  3. 3. 自己紹介 • 本多陽平 • 2012年2月イプロス入社 • Java歴1年半→Scala歴半年 • 現在は広告系サービスの開発を担当 • 去年登山を始めました • サッカーを観たり、梅干しをつけたり、温泉に行ったり、 が趣味 3 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  4. 4. 後半パートについて 後半パートでは、Scalaの • オブジェクト指向要素 • 関数プログラミング要素 の両側面に簡単に触れるとともに、 SBTを使ったビルドについても触れます。 4 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  5. 5. アジェンダ 1. Scalaでオブジェクト指向 1. クラス 2. トレイト ハンズオン 2. Scalaで関数プログラミング 1. 高階関数 ハンズオン 3. SBTによるビルド 1. コンパイル 2. 実行 3. パッケージング ハンズオン ハンズオン ハンズオン 5 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  6. 6. 前置き Scalaの言語仕様を網羅的に説明して いるわけではないので、ご了承下さい 6 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  7. 7. サンプルコードについて 後半パートで使用するサンプルコードは以下 にアップロードしてあります。 イプロス開発ブログ http://ipros-creators.tumblr.com/ ※「イプロス 開発」で検索 7 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  8. 8. オブジェクト指向要素編 Scalaで オブジェクト指向 8 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  9. 9. クラス Scalaは関数型言語であり、 オブジェクト指向言語でもあるので、 クラスを使えます 9 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  10. 10. クラス > コンストラクタ クラス定義 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
  11. 11. クラス > コンストラクタ > 基本コンストラクタ インスタンスが生成される度に呼ばれます 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
  12. 12. クラス > コンストラクタ > クラスパラメータ クラスパラメータは基本コンストラクタのパラメータとなります 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
  13. 13. クラス > コンストラクタ > 補助コンストラクタ 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
  14. 14. クラス > コンストラクタ 基本コンストラクタでインスタンス生成 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
  15. 15. クラス > コンストラクタ 名前は? 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
  16. 16. クラス > コンストラクタ 名前は? 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
  17. 17. クラス > コンストラクタ 名前は? C-1 scala> fuji. asInstanceOf isInstanceOf printName toString scala > fuji.printName res0: String = Mt. Fuj 17 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  18. 18. クラス > コンストラクタ 補助コンストラクタでインスタンス生成 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
  19. 19. クラス > コンストラクタ 名前のない山ができました 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
  20. 20. クラス > コンストラクタ クラスパラメータがフィールドにありません scala> fuji. asInstanceOf isInstanceOf printName 20 C-1 toString COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  21. 21. クラス > コンストラクタ valをつけて定義するとフィールドになります C-2 scala> class Mountain (val name: String) defined class Mountain 21 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  22. 22. クラス > コンストラクタ 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
  23. 23. クラス > コンストラクタ ここまでのまとめ 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. 24. クラス > メソッド メソッド 24 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  25. 25. クラス > メソッド メソッド定義は簡単で、関数定義と同じです C-3 scala> class Mountain (val name: String) { | def erupt = { println("erupted!") }} defined class Mountain ※呼び方(ということが多いです) 関数単体 = 関数 クラス内の関数 = メソッド 25 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  26. 26. クラス > メソッド 呼び出し 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. 27. クラス > ハンズオン 噴火する度に標高が下がる山 を作ってみましょう 27 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  28. 28. クラス > ハンズオン > コーディング例 こんな感じ 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
  29. 29. クラス > ハンズオン > コーディング例 > 動作確認 動かしてみましょう 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
  30. 30. トレイト 実装の定義も可能なJavaのインターフェース という感じです 30 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  31. 31. トレイト 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
  32. 32. トレイト メソッド宣言 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
  33. 33. トレイト メソッド定義 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
  34. 34. トレイト > 具象クラス 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
  35. 35. トレイト > 具象クラス こうした方が親切です(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
  36. 36. トレイト > 抽象フィールド 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
  37. 37. トレイト > 抽象フィールド > 具象クラス 具象クラスの作成 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. 38. トレイト トレイトは複数ミックスインできます 38 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  39. 39. トレイト > 複数トレイトのミックスイン 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
  40. 40. トレイト > 複数トレイトのミックスイン 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
  41. 41. トレイト > 複数トレイトのミックスイン これらをミックスインすると、 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
  42. 42. トレイト > 複数トレイトのミックスイン それぞれの特性を持ったクラスを作ることができます 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
  43. 43. トレイト > まとめ 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
  44. 44. オブジェクト指向要素編 > まとめ Javaと文法が異なり、またJavaにはないトレ イトという概念が存在しますが、Javaと大き く異なる点はありません。 44 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  45. 45. オブジェクト指向要素編 > まとめ JDK 8にはトレイトに似た機能として仮想拡張 メソッド(Virtual Extension Methods)が追加 される予定です 45 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  46. 46. 関数プログラミング要素編 Scalaで関数プログラミング 46 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  47. 47. 関数 > 高階関数 高階関数とは 47 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  48. 48. 関数 > 高階関数 パラメータとして関数を取ったり、 関数を返す関数 48 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  49. 49. 関数 > 高階関数 高階関数の定義 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
  50. 50. 関数 > 高階関数 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
  51. 51. 関数 > 高階関数 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
  52. 52. 関数 > 高階関数 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
  53. 53. 関数 > 高階関数 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
  54. 54. 関数 > 高階関数 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
  55. 55. 関数 > 高階関数 使ってみましょう 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
  56. 56. 関数 > 高階関数 使ってみましょう 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. 57. 関数 > 高階関数 > ハンズオン 文字列をフィルタする関数を実行し、 フィルタの結果を表示する高階関数 を作ってみましょう 57 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  58. 58. 関数 > 高階関数 > ハンズオン > コーディング例 高階関数 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
  59. 59. 関数 > 高階関数 > ハンズオン > コーディング例 フィルタ関数 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
  60. 60. 関数 > 高階関数 > ハンズオン > コーディング例 動作確認 scala> filterBy("明日は晴れると良いな", lengthFilter) not scala> filterBy("明日は雲ひとつない晴天となるでしょう", lengthFilter) passed 60 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  61. 61. 関数 > 高階関数 > カリー化 同じ文字列に対していろんなフィルタをかけ たい時 61 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  62. 62. 関数 > 高階関数 > カリー化 高階関数 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
  63. 63. 関数 > 高階関数 > カリー化 を、カリー化してみる 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
  64. 64. 関数 > 高階関数 > カリー化 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
  65. 65. 関数 > 高階関数 > カリー化 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
  66. 66. 関数 > 高階関数 > カリー化 パラメータを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
  67. 67. 関数 > 高階関数 > カリー化 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. 68. 関数 > 高階関数 > カリー化 > ハンズオン 文字列フィルタを追加し、カリー化した先ほ どの高階関数を使ってフィルタしてみましょ う 68 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  69. 69. 関数 > 高階関数 > カリー化 > ハンズオン > コーディング例 フィルタ関数 scala> def matchingFilter(str: String) = { | if (str.contains("scala")) true | else false } matchingFilter: (str: String)Boolean 69 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  70. 70. 関数 > 高階関数 > カリー化 > ハンズオン > コーディング例 フィルタ対象文字列まで部分適用した関数オブジェクトを作り 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
  71. 71. 関数 > 高階関数 > カリー化 > ハンズオン > コーディング例 フィルタにかけてみます 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
  72. 72. 関数 > 高階関数 > カリー化 > ハンズオン > コーディング例 フィルタにかけてみます 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
  73. 73. 関数編 > さいごに 高階関数と同様の機能がJDK 8には搭載される 予定です 73 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  74. 74. SBT編 SBT 74 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  75. 75. SBT編 目的 • SBTの簡単な説明 • ビルド定義ファイルを書いてみる • jarファイルを作る 75 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  76. 76. SBT > 概要 SBTとはJava, Scala向けビルドツールです (SBT = Simple Build Tool) • コンパイル • 実行 • テスト • パッケージング • ライブラリ管理 などを行えます。 プラグインで機能拡張が可能です。 76 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  77. 77. SBT > 概要 今回は以下を取り上げます • • • • • コンパイル 実行 テスト パッケージング ライブラリ管理 77 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  78. 78. SBT > 構成要素 SBTを利用する場合最低限必要なもの 1. SBT本体 → インストール済み 1. Scalaソースコード → 以降で紹介 2. ビルド定義ファイル → 以降で紹介 78 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  79. 79. SBT > 構成要素 > ディレクトリ構成 SBTプロジェクトのディレクトリ構成 src/ main/ resources/ scala/ java/ test/ resources/ scala/ java/ リソースファイルディレクトリ Scalaソースファイルディレクトリ Javaソースファイルディレクトリ リソースファイルディレクトリ Scalaソースファイル Javaソースファイル ※src配下にある上記以外のディレクトリは無視されます 79 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  80. 80. SBT > ビルド定義ファイル ビルド定義ファイルは2種類あります 1. build.sbt • シンプルなビルド定義であればこちらでOK • 各設定は1行あけて記述する 2. Build.scala • build.sbtで事足りない場合にはこちらを使う • Scalaのコードをそのまま書くことができる 80 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  81. 81. SBT > ビルド定義ファイル 今回はこちらを取り上げます 1. build.sbt • シンプルなビルド定義であればこちらでOK • 各設定は1行あけて記述する 2. Build.scala • build.sbtで事足りない場合にはこちらを使う • Scalaのコードをそのまま書くことができる 81 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  82. 82. SBT > ビルド定義ファイル > build.sbt サンプル name := "hello" version := "1.0" scalaVersion := "2.10.3" 82 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  83. 83. SBT > ビルド定義ファイル > build.sbt プロジェクトの名前です name := "hello" version := "1.0" scalaVersion := "2.10.3" 83 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  84. 84. SBT > ビルド定義ファイル > build.sbt プロジェクトのバージョンです name := "hello" version := "1.0" scalaVersion := "2.10.3" 84 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  85. 85. SBT > ビルド定義ファイル > build.sbt 使用するScalaのバージョンです name := "hello" version := "1.0" scalaVersion := "2.10.3" 85 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  86. 86. 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
  87. 87. SBT > ハンズオン① ディレクトリ構成 S-3 src/ build.sbt main/ scala/ Hello.scala 87 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  88. 88. 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
  89. 89. 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
  90. 90. SBT > ハンズオン① 続いて実行してみます > run 90 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  91. 91. 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
  92. 92. SBT > ハンズオン② パッケージングも簡単です > package 92 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  93. 93. 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
  94. 94. 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
  95. 95. 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
  96. 96. SBT > ハンズオン③ packageで生成するjarファイル名を scala-handson_2.10-9.9.jar に変えてみましょう 96 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  97. 97. SBT > ハンズオン③ > 設定例 build.sbtを変えます name := "scala-handson" version := "9.9" scalaVersion := "2.10.3" 97 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  98. 98. 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
  99. 99. 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
  100. 100. SBT > プラグイン プラグインを利用すれば、大抵のことはでき ます。 イプロスではJenkinsと併せて、ビルド、DB マイグレーション、デプロイまでをSBTで実 施しています。 100 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  101. 101. まとめ まとめ 101 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  102. 102. まとめ イプロスでは広告系システムの開発にScalaを 導入し、REST APIサービス及びバッチを開発 しています。 Scalaの持つ概念の一部がJDK 8でも取り入れ られる予定であることから、今日ご紹介した 内容は今後当たり前になっていくと思います。 102 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  103. 103. まとめ この勉強会がScalaを学ぶ契機となったならば 幸いです。 103 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED
  104. 104. おしまい ありがとうございました 104 COPYRIGHT © 2013 IPROS CORPORATION ALL RIGHTS RESERVED

×