$30 off During Our Annual Pro Sale. View Details »

Scalaリファクタリング入門「大改造!静的ビフォー・アフター」

 Scalaリファクタリング入門「大改造!静的ビフォー・アフター」

「Better Javaの一歩先へ! Scalaリファクタリング入門」@ビズリーチD3勉強会 第一部の資料です。

Shunsuke Tadokoro

December 05, 2016
Tweet

More Decks by Shunsuke Tadokoro

Other Decks in Programming

Transcript

  1. େ վ ଄ ʂ ੩ త Ϗ ϑ Υ ʔ ɾ Ξ ϑ λ ʔ
    d
    4DBMBϦϑΝΫλϦϯάೖ໳
    !UPEPLS
    . : ✨

    View Slide

  2. #FUUFS+BWBͳίʔυ
    4DBMBΒ͠͞Λ׆͔͠ɺΑΓݎ࿚ʹ

    View Slide

  3. ా ॴ ॣ ༎ ! U P E P L S
    ג ࣜ ձ ࣾ Ϗ ζ Ϧ ʔ ν 

    ελ ϯόΠ ࣄ ۀ ෦ α ʔ ν ί Ξάϧ ʔϓ 

    ΢ Σ ϒΫ ϩ ʔ ϥ ʔ ͷ ։ ൃ ɾ ӡ ༻
    ೥ ݄ ೖ ࣾ ࡀ
    4 D B M B ྺ ೥ ϲ ݄

    View Slide

  4. ͓ ࿩ ͢͠ Δ ͜ ͱ
    w ͳͥ#FUUFS+BWBͷઌͳͷ͔ʁ4DBMBΒ͠͞ͷԸܙͱ͸
    w ύλʔϯϚονͷύλʔϯΩϟετΛͳͯ҆͘͠શʹ
    w λϓϧΛආ͚Δͦͷ਺ࣈʹҙຯ͸͋Δ͔ʁ
    w 4DBMBͳྫ֎ॲཧ੒ޭɾࣦഊΛ஋ͱͯ͠දݱ͢Δ
    w DBTFDMBTTʹ੍໿Λ࣋ͨͤΔSFRVJSFͷར༻
    w TFBMFEUSBJUͰ໢ཏੑΛ୲อ͢ΔίϯύΠϥʹ͓ئ͍

    View Slide

  5. ͓ ࿩ ͢͠ Δ ͜ ͱ
    w ͳͥ#FUUFS+BWBͷઌͳͷ͔ʁ4DBMBΒ͠͞ͷԸܙͱ͸
    w ύλʔϯϚονͷύλʔϯΩϟετΛͳͯ҆͘͠શʹ
    w λϓϧΛආ͚Δͦͷ਺ࣈʹҙຯ͸͋Δ͔ʁ
    w 4DBMBͳྫ֎ॲཧ੒ޭɾࣦഊΛ஋ͱͯ͠දݱ͢Δ
    w DBTFDMBTTʹ੍໿Λ࣋ͨͤΔSFRVJSFͷར༻
    w TFBMFEUSBJUͰ໢ཏੑΛ୲อ͢ΔίϯύΠϥʹ͓ئ͍
    ˠ 4 D B M B Λ ֶ ͼ ࢝ Ί ͨ ࠒ ͷ ࣗ ෼ ʹ 

    ɹ ڭ ͑ͯ ͋ ͛ ͨ ͍ ಺ ༰

    View Slide

  6. ͳ ͥ # F U U F S + B W B ͷ ઌ ͳ ͷ ͔ ʁ

    View Slide

  7. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ

    View Slide

  8. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ

    View Slide

  9. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ
    ͪΐͬͱ௕͍

    View Slide

  10. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ
    ίʔυͷ௕͞ͱόάͷೖΓ΍͢͞͸

    ਖ਼ൺྫ͢ΔɻͰ͖Ε͹΋ͬͱ୹͍ͨ͘͠ɻ
    ͪΐͬͱ௕͍

    View Slide

  11. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ

    View Slide

  12. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ
    ग़ޱ͕Օॴ

    View Slide

  13. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ
    ग़ޱ͕Օॴ
    Ͱ͖Ε͹෼ذ͸গͳ͍΄͏͕

    γϯϓϧͰݎ࿚ɻ

    View Slide

  14. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ

    View Slide

  15. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ
    ࠶୅ೖՄೳͳม਺

    View Slide

  16. 1 def isBlank(str:String): Boolean = {
    2 var strLen = 0
    3
    4 if(str == null || { strLen = str.length(); strLen } == 0) {
    5 return true
    6 }
    7
    8 var i = 0
    9 while( i < strLen ){
    10 if(Character.isWhitespace( str.charAt(i) ) == false){
    11 return false
    12 }
    13 i += 1
    14 }
    15
    16 return true
    17 }
    # F U U F S + B W B ͳ ελ Πϧ
    ࠶୅ೖՄೳͳม਺
    ࠶୅ೖՄೳʮঢ়ଶʯΛ࣋ͭͱ͍͏͜ͱɻ

    ঢ়ଶΛؾʹ͢Δඞཁ͕͋Δɻ

    View Slide

  17. 1 def isBlank(str: String): Boolean =
    2 Option(str).fold(true)(_.forall(Character.isWhitespace))
    4 D B M B Β ͠ ͍ ελ Πϧ

    View Slide

  18. 1 def isBlank(str: String): Boolean =
    2 Option(str).fold(true)(_.forall(Character.isWhitespace))
    w ୹͘ಡΈ΍͘͢
    w ෼ذ͕গͳ͘
    w ঢ়ଶΛؾʹ͢Δඞཁͳ͘
    4 D B M B Β ͠ ͍ ελ Πϧ

    View Slide

  19. 1 def isBlank(str: String): Boolean =
    2 Option(str).fold(true)(_.forall(Character.isWhitespace))
    w ୹͘ಡΈ΍͘͢
    w ෼ذ͕গͳ͘
    w ঢ়ଶΛؾʹ͢Δඞཁͳ͘
    4 D B M B Β ͠ ͍ ελ Πϧ
    ☺ όάͷࠞೖͷՄೳੑ͕Լ͕Δ

    View Slide

  20. ύ λ ʔϯ Ϛ ο ν ͷ ύ λ ʔϯ

    View Slide

  21. 0 Q U J P O ͷ ύ λ ʔϯ Ϛ ο ν
    1 option match {
    2 case Some(x) => println(s"$x is here!")
    3 case None => println("oh…")
    4 }

    View Slide

  22. γ ʔ έ ϯε ͷ ύ λ ʔϯ Ϛ ο ν
    1 List("Noel", "Liam", "Gem", "Andy", "Alan") match {
    2 case List(_, second, _*) => println(s"Hello $second!")
    3 case _ =>
    4 }
    5 // => Hello Liam!

    View Slide

  23. ί ϯε τ ϥ Ϋ λύ λ ʔϯ
    1 val user = User("Martin", Place("Tokyo", "Shibuya"))
    2
    3 user match {
    4 case User(name, Place(pref, _)) => "$name in $pref"
    5 case _ =>
    6 }
    7 // => Martin lives in Tokyo!

    View Slide

  24. ܕ ν Σ ο Ϋ ͱ Ω ϟε τ
    1 def count2x(x: Any): Int = {
    2 if (x.isInstanceOf[String]) {
    3 x.asInstanceOf[String].length * 2
    4 } else if (x.isInstanceOf[Int]) {
    5 x.asInstanceOf[Int] * 2
    6 } else -1
    7 }
    8
    9 count2x("scala") // 10
    10 count2x(7) // 14

    View Slide

  25. ܕ ν Σ ο Ϋ ͱ Ω ϟε τ
    1 def count2x(x: Any): Int = {
    2 if (x.isInstanceOf[String]) {
    3 x.asInstanceOf[String].length * 2
    4 } else if (x.isInstanceOf[Int]) {
    5 x.asInstanceOf[Int] * 2
    6 } else -1
    7 }
    8
    9 count2x("scala") // 10
    10 count2x(7) // 14
    ܕνΣοΫ

    View Slide

  26. ܕ ν Σ ο Ϋ ͱ Ω ϟε τ
    1 def count2x(x: Any): Int = {
    2 if (x.isInstanceOf[String]) {
    3 x.asInstanceOf[String].length * 2
    4 } else if (x.isInstanceOf[Int]) {
    5 x.asInstanceOf[Int] * 2
    6 } else -1
    7 }
    8
    9 count2x("scala") // 10
    10 count2x(7) // 14
    Ωϟετ

    View Slide

  27. ܕ ν Σ ο Ϋ ͱ Ω ϟε τ
    1 def count2x(x: Any): Int = {
    2 if (x.isInstanceOf[String]) {
    3 x.asInstanceOf[String].length * 2
    4 } else if (x.isInstanceOf[Int]) {
    5 x.asInstanceOf[Int] * 2
    6 } else -1
    7 }
    8
    9 count2x("scala") // 10
    10 count2x(7) // 14
    Ωϟετ
    গ͠৑௕ɻ
    Θ͟Θ͟Ωϟετ͢Δͷ΋ةݥͳ߳Γɻ
    ܕνΣοΫ

    View Slide

  28. ܕ ෇ ͖ ύ λ ʔϯ
    1 def count2x(x: Any): Int = x match {
    2 case x:String => x.length * 2
    3 case x: Int => x * 2
    4 case _ => -1
    5 }
    6
    7 count2x("scala") // 10
    8 count2x(7) // 14

    View Slide

  29. ܕ ෇ ͖ ύ λ ʔϯ
    1 def count2x(x: Any): Int = x match {
    2 case x:String => x.length * 2
    3 case x: Int => x * 2
    4 case _ => -1
    5 }
    6
    7 count2x("scala") // 10
    8 count2x(7) // 14 ☺ ίʔυͷݟ௨͕͠޲্ɻ

    Ωϟετ΋ෆཁͰ҆৺ɻ

    View Slide

  30. ܕ ফ ڈ ʹ ஫ ҙ
    1 def detectType(x: Any): String = x match {
    2 case x: List[Int] => "This is List of Int!"
    3 case _ => "What?"
    4 }
    5
    6 detectType(List("string!")) // => This is List of Int!

    View Slide

  31. ܕ ফ ڈ ʹ ஫ ҙ
    1 def detectType(x: Any): String = x match {
    2 case x: List[Int] => "This is List of Int!"
    3 case _ => "What?"
    4 }
    5
    6 detectType(List("string!")) // => This is List of Int!
    +BWBͱಉ༷ɺίϨΫγϣϯͷཁૉܕͷ৘ใ͸

    ࣮ߦ࣌ʹ͸؅ཧ͞Εͳ͍ ˞"SSBZΛআ͘

    View Slide

  32. λ ϓϧ Λ ආ ͚ Δ

    View Slide

  33. λ ϓϧ
    1 // ঎඼
    2 case class Item(name: String, price: Int)
    3
    4 // ঎඼ͷ੫ࠐՁ֨ͱՁ֨ϥϕϧΛฦ͢
    5 def labelPriceWithTax(item: Item): (Int, String) = {
    6 val withTax = item.price * 1.08
    7 val label = s"ܹ҆େಛՁ ¥${item.price}ʢ੫ࠐʣ"
    8 (withTax, label)
    9 }

    View Slide

  34. λ ϓϧ
    1 // ঎඼
    2 case class Item(name: String, price: Int)
    3
    4 // ঎඼ͷ੫ࠐՁ֨ͱՁ֨ϥϕϧΛฦ͢
    5 def labelPriceWithTax(item: Item): (Int, String) = {
    6 val withTax = item.price * 1.08
    7 val label = s"ܹ҆େಛՁ ¥${item.price}ʢ੫ࠐʣ"
    8 (withTax, label)
    9 }
    ☺ +BWBͰ͸-JTU0CKFDUͷΑ͏ʹฦ͍ͯͨ͠΋ͷ͕

    ܕͷ৘ใΛΩʔϓͨ͠··ฦͤͯ҆৺

    View Slide

  35. Ξ ϯ νύ λ ʔϯ Ξ ϯ μʔε ί Ξ Ͱ ͷ ΞΫ η ε
    1 val apple = Item("αϯ;͡", 158)
    2 val x = labelPriceWithTax(apple)
    3 println(s"${x._1}͕ͳΜͱ${x._2}!")
    4 // αϯ;͕͡ͳΜͱܹ҆େಛՁ ¥158!

    View Slide

  36. Ξ ϯ νύ λ ʔϯ Ξ ϯ μʔε ί Ξ Ͱ ͷ ΞΫ η ε
    1 val apple = Item("αϯ;͡", 158)
    2 val x = labelPriceWithTax(apple)
    3 println(s"${x._1}͕ͳΜͱ${x._2}!")
    4 // αϯ;͕͡ͳΜͱܹ҆େಛՁ ¥158!
    ʮY@ʯͷͳͲͷ਺ࣈ͸

    ཁૉʹ͍ͭͯͷ৘ใΛԿ΋఻͍͑ͯͳ͍ɻ

    औΓҧ͑ͯ΋ؾ͖ͮͮΒ͍ɻ

    View Slide

  37. վ ળ ྫ ม ਺ ୅ ೖ ࣌ ʹ λ ϓϧ Λ ෼ ղ
    1 val apple = Item("αϯ;͡", 158)
    2 val (name, priceLabel) = labelPriceWithTax(apple)
    3 println(s"${name}͕ͳΜͱ${priceLabel}!")
    4 // αϯ;͕͡ͳΜͱܹ҆େಛՁ ¥158!
    ҙຯͷ͋Δม਺໊ͰΞΫηεͰ͖ͯ҆৺

    ม਺͕૿͑ͯ΋औΓҧ͑ʹ͍͘

    View Slide

  38. վ ળ ྫ ύ λ ʔϯ Ϛ ο ν Ͱ λ ϓϧ Λ ෼ ղ
    1 val apple = Item("αϯ;͡", 158)
    2 labelPriceWithTax(apple) match { case (name, price) =>
    3 println(s"${name}͕ͳΜͱ${price}!")
    4 }
    5 // αϯ;͕͡ͳΜͱܹ҆େಛՁ ¥158!

    View Slide

  39. 4 D B M B ͳ ྫ ֎ ॲ ཧ

    View Slide

  40. ྫ ֎ ॲ ཧ
    1 // ྫ֎Λ౤͛ΔՄೳੑͷ͋Δϝιου
    2 def detect(bytes: Array[Byte]): Charset = {
    3 val detectedCharsetName: String = ...
    4 Charset.forName(detectedCharsetName)
    5 }
    6
    7 // ϝιουͷݺͼग़͠ݩͰྫ֎ॲཧ
    8 try {
    9 detect(bytes)
    10 ...
    11 } catch {
    12 case e: Exception => ...
    13 }

    View Slide

  41. ྫ ֎ ॲ ཧ
    1 // ྫ֎Λ౤͛ΔՄೳੑͷ͋Δϝιου
    2 def detect(bytes: Array[Byte]): Charset = {
    3 val detectedCharsetName: String = ...
    4 Charset.forName(detectedCharsetName)
    5 }
    6
    7 // ϝιουͷݺͼग़͠ݩͰྫ֎ॲཧ
    8 try {
    9 detect(bytes)
    10 ...
    11 } catch {
    12 case e: Exception => ...
    13 }
    ੒ޭPSࣦഊΛ஋ͱͯ͠ѻ͍ɺ

    ੍ޚϑϩʔΛγϯϓϧʹ͍ͨ͠

    View Slide

  42. ྫ ֎ Ͱ ͸ ͳ ͘ ʜ
    ੒ޭPSࣦഊΛදݱ͢Δܕͱͦͷ஋Λ༻͍Δ
    w 0QUJPO<5>

    ੒ޭ࣌ͷ஋Λ4PNFɺࣦഊΛ/POFͰදݱ
    w &JUIFS<" #>

    ੒ޭ࣌ͷ৘ใΛ3JHIUͰɺࣦഊͷ৘ใΛ-FGUͰදݱ
    w 5SZ<5>

    ྫ֎Λ౤͛ΔՄೳੑͷ͋ΔॲཧΛந৅Խɺ4VDDFTTͱ'BJMVSFͰ݁ՌΛදݱ

    View Slide

  43. 0 Q U J P O ܕ
    w 4PNFͱ/POFͱ͍͏छྨ
    w ஋͕ଘࡏ͢Δ͜ͱΛද͢4PNF W

    w ஋͕ଘࡏ͠ͳ͍͜ͱΛද͢/POF
    w 0QUJPOܕˠʮ஋͕ଘࡏ͠ͳ͍Մೳੑ͕͋Δʯͱ͍͏ϝοηʔδ

    View Slide

  44. 0 Q U J P O Ͱ ੒ ޭ ࣦ ഊ Λ ද ݱ ͢ Δ
    1 // try / catchͰOptionΛฦ͢
    2 def detect(bytes: Array[Byte]): Option[Charset] = {
    3 val detectedCharsetName: String = ...
    4 try {
    5 Some(Charset.forName(detectedCharsetName))
    6 } catch {
    7 case e: Exception => None
    8 }
    9 }
    ੒ޭ࣌͸4PNFɺࣦഊ࣌͸/POFͰฦ͢

    View Slide

  45. 0 Q U J P O Ͱ ੒ ޭ ࣦ ഊ Λ ද ݱ ͢ Δ
    1 // ࣦഊͨ͠ΒσϑΥϧτ஋Λ࢖͏
    2 detect(bytes).getOrElse(Charset.defaultCharset)
    3
    4 // ࣦഊͨ͠ΒԿ΋͠ͳ͍
    5 detect(bytes).map { charset =>
    6 // Կ͔ॲཧ
    7 }
    ݺͿଆͰͷѻ͍
    ݁ՌʹԠͨ͡ॲཧ͕҆શ͔ͭॊೈʹͰ͖Δ

    View Slide

  46. & J U I F S ܕ
    w 3JHIU D
    ͱ-FGU F
    ͱ͍͏छྨ
    w 3JHIU͸ʮਖ਼͍͠ʯʹ͔͚ͯ੒ޭ࣌ͷ஋Λ֨ೲ͢Δͷ͕ओྲྀ
    w -FGU΋஋Λ࣋ͯΔͷͰɺࣦഊ࣌ͷ৘ใΛ֨ೲͰ͖Δ
    w &JUIFSܕˠʮࣦഊ͢ΔՄೳੑ͕͋Δʯͱ͍͏ϝοηʔδ

    View Slide

  47. & J U I F S Ͱ ੒ ޭ ࣦ ഊ Λ ද ݱ ͢ Δ
    1 // try / catchͰOptionΛฦ͢
    2 def detect(bytes: Array[Byte]): Either[Exception, Charset] = {
    3 val detectedCharsetName: String = ...
    4 try {
    5 Right(Charset.forName(detectedCharsetName))
    6 } catch {
    7 case e: Exception => Left(e)
    8 }
    9 }
    ੒ޭ࣌͸3JHIUɺࣦഊ࣌͸-FGUͰฦ͢

    View Slide

  48. & J U I F S Ͱ ੒ ޭ ࣦ ഊ Λ ද ݱ ͢ Δ
    1 //
    2 val charset = detect(bytes) match {
    3 case Right(charset) => charset
    4 case Left(e) =>
    5 logger.error(s"Oops! :$e")
    6 Charset.defaultCharset
    7 }
    ݺͿଆͰͷѻ͍
    ݺͼग़͢ਓʹ݁ՌͷνΣοΫΛڧ੍Ͱ͖Δ

    ࣦഊ࣌ͷ৘ใ͕࣋ͯΔͷͰϩάʹग़ͨ͠ΓͳͲ

    View Slide

  49. 5S Z ܕ
    w 4VDDFTT W
    ͱ'BJMVSF F
    ͱ͍͏छྨ
    w 4VDDFTT W
    ʹ੒ޭ࣌ͷ஋
    w 'BJMVSF F
    ʹࣦഊ࣌ͷ৘ใ
    w ྫ֎͕౤͛ΒΕΔ͔΋͠Εͳ͍ॲཧΛ5SZͰғΉ͚ͩͰ0,
    w 5SZܕˠʮࣦഊ͢ΔՄೳੑ͕͋Δʯͱ͍͏ϝοηʔδ

    View Slide

  50. 5S Z Ͱ ੒ ޭ ࣦ ഊ Λ ද ݱ ͢ Δ
    1 // ݁ՌΛTryͰड͚औΔ
    2 import scala.util.Try
    3 def detect(bytes: Array[Byte]): Try[Charset] = {
    4 val detectedCharsetName: String = ...
    5 Try(Charset.forName(ud.getDetectedCharset))
    6 }
    7
    ࣦഊ͢Δ͔΋͠Εͳ͍ॲཧΛ5SZ
    ͰแΉ

    View Slide

  51. 5S Z Ͱ ੒ ޭ ࣦ ഊ Λ ද ݱ ͢ Δ
    1 //
    2 val charset = detect(bytes) match {
    3 case Success(charset) => charset
    4 case Failure(e) =>
    5 logger.error(s"Oops! :$e")
    6 Charset.defaultCharset
    7 }
    ݺͿଆͰͷѻ͍
    4VDDFTT'BJMVSFͰύλʔϯϚον

    View Slide

  52. ' B J M V S F ʹ ͳ Δ ͷ ͸ / P O ' B U B M ͳ ΋ ͷ
    • VirtualMachineError
    • ThreadDeath
    • InterruptedException
    • LinkageError
    • ControlThrowable
    'BUBMͳΤϥʔɾྫ֎͸ͦͷ··εϩʔ͞ΕΔ

    View Slide

  53. 5S Z ͱ G P S ࣜ
    1 // ྫ֎Λى͔͜͢΋͠Εͳ͍ϝιου
    2 def someMethod: Int = ???
    3 def anotherMethod: Int = ???

    View Slide

  54. 5S Z ͱ G P S ࣜ
    1 // TryΛforࣜͰ߹੒͢Δ
    2 val result = for {
    3 result1 <- Try(someMethod)
    4 result2 <- Try(anotherMethod)
    5 } yield result1 + result2
    6
    7 result match {
    8 case Success(result) => println(result)
    9 case Failure(e) => println(s"Opps: ", e)
    10 }

    View Slide

  55. 5S Z ͱ G P S ࣜ
    1 // TryΛforࣜͰ߹੒͢Δ
    2 val result = for {
    3 result1 <- Try(someMethod)
    4 result2 <- Try(anotherMethod)
    5 } yield result1 + result2
    6
    7 result match {
    8 case Success(result) => println(result)
    9 case Failure(e) => println(s"Opps: ", e)
    10 }
    ʮ"ͱ#͕྆ํ੒ޭͨ͠ͱ͖ͷΈ9͢Δʯ

    ͳͲ͕෼͔Γ΍͘͢දݱͰ͖Δ

    View Slide

  56. D B T F D M B T T ʹ ੍ ໿ Λ ࣋ ͨ ͤ Δ

    View Slide

  57. Ұ ݟ ͳ Μ ͷ ม ఩ ΋ ͳ ͍ D B T F D M B T T
    1 case class Person(
    2 name: String,
    3 age: Int
    4 )

    View Slide

  58. Ұ ݟ ͳ Μ ͷ ม ఩ ΋ ͳ ͍ D B T F D M B T T
    1 case class Person(
    2 name: String,
    3 age: Int
    4 )
    ࡀͱ͔͸ͳ͍ΑͶɻ

    Ҿ਺ΛνΣοΫ͠ͳ͖Όɻ

    View Slide

  59. 1 case class Person(
    2 name: String,
    3 age: Int
    4 ) {
    5 if(age < 0)
    throw new IllegalArgumentException("Age must be natural!")
    6 }
    ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F D M B T T

    View Slide

  60. 1 case class Person(
    2 name: String,
    3 age: Int
    4 ) {
    5 if(age < 0)
    throw new IllegalArgumentException("Age must be natural!")
    6 }
    ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F D M B T T
    ࣄલ৚݅Ͱ͋Δ͜ͱΛ

    ΋ͬͱ໌֬ʹ఻͍͑ͨ

    View Slide

  61. 1 case class Person(
    2 name: String,
    3 age: Int
    4 ) {
    5 require(age >= 0, "Age must be natural number!")
    6 }
    ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F D M B T T

    View Slide

  62. 1 case class Person(
    2 name: String,
    3 age: Int
    4 ) {
    5 require(age >= 0, "Age must be natural number!")
    6 }
    ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F D M B T T
    ࣄલ৚݅

    View Slide

  63. 1 case class Person(
    2 name: String,
    3 age: Int
    4 ) {
    5 require(age >= 0, "Age must be natural number!")
    6 }
    ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F D M B T T
    ࣄલ৚݅Λຬͨ͞ͳ͍৔߹ͷ

    Τϥʔϝοηʔδ

    View Slide

  64. 1 case class Person(
    2 name: String,
    3 age: Int
    4 ) {
    5 require(age >= 0, "Age must be natural number!")
    6 }
    ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F D M B T T
    1 val joe = Person("Joe Cool", -2))

    View Slide

  65. 1 case class Person(
    2 name: String,
    3 age: Int
    4 ) {
    5 require(age >= 0, "Age must be natural number!")
    6 }
    ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F D M B T T
    1 val joe = Person("Joe Cool", -2))
    2 // => java.lang.IllegalArgumentException:
    requirement failed: Age must be natural number!

    View Slide

  66. 1 case class Person(
    2 name: String,
    3 age: Int
    4 ) {
    5 require(age >= 0, "Age must be natural number!")
    6 }
    ੍ ໿ Λ ΋ ͨ ͤ ͨ D B T F D M B T T
    &JUIFS΍5SZͱ૊Έ߹ΘͤΔͱ͏Ε͍͠

    1 val joe = Person("Joe Cool", -2))
    2 // => java.lang.IllegalArgumentException:
    requirement failed: Age must be natural number!

    View Slide

  67. T F B M F E U S B J U Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ

    View Slide

  68. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ Ϛ ο ν
    1 case class User(name: String, age: Int)

    View Slide

  69. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ Ϛ ο ν
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan // ແྉϓϥϯ
    5 case class Premium(user: User) extends Plan // ϓϨϛΞϜϓϥϯ

    View Slide

  70. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ Ϛ ο ν
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan // ແྉϓϥϯ
    5 case class Premium(user: User) extends Plan // ϓϨϛΞϜϓϥϯ
    6
    7 val userA = Free(User("Taro", 23))
    8 val userB = Premium(User("Jiro", 25))
    9

    View Slide

  71. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ Ϛ ο ν
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan // ແྉϓϥϯ
    5 case class Premium(user: User) extends Plan // ϓϨϛΞϜϓϥϯ
    6
    7 val userA = Free(User("Taro", 23))
    8 val userB = Premium(User("Jiro", 25))
    9
    10 userB match {
    11 case Free(User(name, _)) => println(s"Hi, $name.")
    12 case Premium(User(name, _)) => println(s"Hello, $name!")
    13 }

    View Slide

  72. Ϣ ʔ β ʔϓ ϥ ϯ Λ ύ λ ʔϯ Ϛ ο ν
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan // ແྉϓϥϯ
    5 case class Premium(user: User) extends Plan // ϓϨϛΞϜϓϥϯ
    6
    7 val userA = Free(User("Taro", 23))
    8 val userB = Premium(User("Jiro", 25))
    9
    10 userB match {
    11 case Free(User(name, _)) => println(s"Hi, $name.")
    12 case Premium(User(name, _)) => println(s"Hello, $name!")
    13 }
    14 // => Hello, Jiro!

    View Slide

  73. ϓ ϥ ϯ Λ ૿ ΍ ͢
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan
    5 case class Premium(user: User) extends Plan

    View Slide

  74. ϓ ϥ ϯ Λ ૿ ΍ ͢
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan
    5 case class Premium(user: User) extends Plan
    6 case class Campaign(user: User) extends Plan
    7
    8 val userA = Free(User("Taro", 23))
    9 val userB = Premium(User("Jiro", 25))
    10 val userC = Campaign(User("Saburo", 28))

    View Slide

  75. ϓ ϥ ϯ Λ ૿ ΍ ͢
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan
    5 case class Premium(user: User) extends Plan
    6 case class Campaign(user: User) extends Plan
    7
    8 val userA = Free(User("Taro", 23))
    9 val userB = Premium(User("Jiro", 25))
    10 val userC = Campaign(User("Saburo", 28))
    11
    12 Seq(userA, userB, userC) foreach {
    13 case Free(User(name, _)) => println(s"Hi, $name.")
    14 case Premium(User(name, _)) => println(s"Hello, $name!")
    15 }

    View Slide

  76. ϓ ϥ ϯ Λ ૿ ΍ ͢
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan
    5 case class Premium(user: User) extends Plan
    6 case class Campaign(user: User) extends Plan
    7
    8 val userA = Free(User("Taro", 23))
    9 val userB = Premium(User("Jiro", 25))
    10 val userC = Campaign(User("Saburo", 28))
    11
    12 Seq(userA, userB, userC) foreach {
    13 case Free(User(name, _)) => println(s"Hi, $name.")
    14 case Premium(User(name, _)) => println(s"Hello, $name!")
    15 }
    16 // => Hi, Taro.
    17 // => Hello, Jiro!
    18 // => scala.MatchError: Campaign(User(Saburo,28)) …

    View Slide

  77. ϓ ϥ ϯ Λ ૿ ΍ ͢
    1 case class User(name: String, age: Int)
    2
    3 trait Plan
    4 case class Free(user: User) extends Plan
    5 case class Premium(user: User) extends Plan
    6 case class Campaign(user: User) extends Plan
    7
    8 val userA = Free(User("Taro", 23))
    9 val userB = Premium(User("Jiro", 25))
    10 val userC = Campaign(User("Saburo", 28))
    11
    12 Seq(userA, userB, userC) foreach {
    13 case Free(User(name, _)) => println(s"Hi, $name.")
    14 case Premium(User(name, _)) => println(s"Hello, $name!")
    15 }
    16 // => Hi, Taro.
    17 // => Hello, Jiro!
    18 // => scala.MatchError: Campaign(User(Saburo,28)) …
    .BUDI&SSPS͸࣮ߦ࣌Τϥʔɻ

    ࣮ߦલʹύλʔϯͷ࿙Εʹؾ͖͍ͮͨ

    View Slide

  78. 4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ
    1 case class User(name: String, age: Int)
    2
    3 trait Plan

    View Slide

  79. 4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ
    1 case class User(name: String, age: Int)
    2
    3 sealed trait Plan

    View Slide

  80. 4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ
    1 case class User(name: String, age: Int)
    2
    3 sealed trait Plan
    w ಉ͡ϑΝΠϧ಺Ͱ͸ܧঝՄೳ
    w ผͷϑΝΠϧ͔Β͸ܧঝෆՄ

    View Slide

  81. 4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ
    1 case class User(name: String, age: Int)
    2
    3 sealed trait Plan
    w ಉ͡ϑΝΠϧ಺Ͱ͸ܧঝՄೳ
    w ผͷϑΝΠϧ͔Β͸ܧঝෆՄ
    ͜ͷϑΝΠϧ಺Ͱఆٛ͞Εͨ΋ͷҎ֎ʹ

    1MBO͸ଘࡏ͠ͳ͍͜ͱ͕อূ͞ΕΔ

    View Slide

  82. 4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ
    1 case class User(name: String, age: Int)
    2
    3 sealed trait Plan
    4 case class Free(user: User) extends Plan
    5 case class Premium(user: User) extends Plan
    6 case class Campaign(user: User) extends Plan
    7
    8 val userA = Free(User("Taro", 23))
    9 val userB = Premium(User("Jiro", 25))
    10 val userC = Campaign(User("Saburo", 28))
    11
    12 Seq(userA, userB, userC) foreach {
    13 case Free(User(name, _)) => println(s"Hi, $name.")
    14 case Premium(User(name, _)) => println(s"Hello, $name!")
    15 }

    View Slide

  83. [warn] It would fail on the following input: Campaign(_)
    [warn] Seq(userA, userB, userC) foreach {
    [warn] ^
    [warn] one warning found
    4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ
    ίϯύΠϧ͢Δͱʜ
    ʮ$BNQBJHO͕དྷͨΒམͪΔ΍Ͱʂʯͱ
    ίϯύΠϥ͕ڭ͑ͯ͘ΕΔ

    View Slide

  84. [warn] It would fail on the following input: Campaign(_)
    [warn] Seq(userA, userB, userC) foreach {
    [warn] ^
    [warn] one warning found
    4 F B M F E म ০ ࢠ Ͱ ໢ ཏ ੑ Λ ୲ อ ͢ Δ
    ίϯύΠϧ͢Δͱʜ
    ʮ$BNQBJHO͕དྷͨΒམͪΔ΍Ͱʂʯͱ
    ίϯύΠϥ͕ڭ͑ͯ͘ΕΔ

    8BSOJOHແࢹ͠ͳ͍ͰͶ

    View Slide

  85. ͓ ࿩ ͠ ͠ ͨ ͜ ͱ
    w ͳͥ#FUUFS+BWBͷઌͳͷ͔ʁ
    w ύλʔϯϚονͷύλʔϯ
    w λϓϧΛආ͚Δ
    w 4DBMBͳྫ֎ॲཧ
    w DBTFDMBTTʹ੍໿Λ࣋ͨͤΔ
    w TFBMFEUSBJUͰ໢ཏੑΛ୲อ͢Δ

    View Slide

  86. ) B W F B ( P P E 4 D B M B - J G F
    . : ✨

    View Slide