Upgrade to Pro — share decks privately, control downloads, hide ads and more …

構造的差分ライブラリ開発時の悲劇・喜劇

Kuniwak
October 13, 2017

 構造的差分ライブラリ開発時の悲劇・喜劇

Kuniwak

October 13, 2017
Tweet

More Decks by Kuniwak

Other Decks in Programming

Transcript

  1. func testExample1() { let a = Example( key1: "I'm not

    changed", key2: "I'm deleted" ) let b = Example( key1: "I'm not changed", key2: "I'm inserted" ) XCTAssertEqual(a, b) } Α͋͘ΔTUSVDUͷൺֱ
  2. XCTAssertEqual failed: ("Example(key1: "I\'m not changed", key2: "I\'m deleted")") is

    not equal to ("Example(key1: "I\'m not changed", key2: "I\'m inserted")") - ςετ݁Ռ͸ඇৗʹΘ͔ΓͮΒ͍
  3. import MirrorDiffKit func testExample2() { let a = Example( key1:

    "I'm not changed", key2: "I'm deleted" ) let b = Example( key1: "I'm not changed", key2: "I'm inserted" ) XCTAssertEqual(a, b, diff(between: a, and: b)) } ࣦഊ࣌ͷϝοηʔδʹ
 .JSSPS%J⒎,JUͷEJ⒎Λࢦఆ .JSSPS%J⒎,JUΛJNQPSU
  4. struct Example { key1: "I'm not changed" - key2: "I'm

    deleted" + key2: "I'm inserted" } ͜Ε͕ߏ଄తͳࠩ෼ ͙͢ʹࠩҟ͕Θ͔Γ·͢
  5. [ "I'm not changed" "I'm not changed" - "I'm deleted"

    "I'm not changed" + "I'm inserted" ] ഑ྻͷॱংมߋͳͲ΋
 ߏ଄తͳࠩ෼Ͱ͢ ͜Ε΋ݟ΍͘͢දࣔ͞Ε·͢
  6. let example = Example( key1: "I'm not changed", key2: "I'm

    deleted" ) let hint = ( subject: Example.self, displayStyle: .struct, children: [ (label: "key1", value: "I'm not changed"), (label: "key2", value: "I'm deleted"), ] ) ߏ଄తͳࠩ෼ͷܭࢉʹ͸ɺ
 ࣍ͷΑ͏ͳΦϒδΣΫτͷ
 ߏ଄ͷώϯτ͕ෆՄܽͰ͢ ΦϒδΣΫτͷܕ ΦϒδΣΫτͷछྨ ϓϩύςΟͷ໊લͱ஋
  7. let example = Example( key1: "I'm not changed", key2: "I'm

    deleted" ) let mirror = Mirror(reflecting: example) let hint = ( subject: mirror.subjectType, displayStyle: mirror.displayStyle, children: mirror.children ) ௐ΂͍ͨΦϒδΣΫτ͔Β
 .JSSPSΦϒδΣΫτΛ
 ࡞੒͢Δͱɺ ܕ৘ใ΍ΦϒδΣΫτͷछྨɺ
 ϓϩύςΟͷ໊લͱ஋ͳͲΛ
 ೖखͰ͖·͢
  8. struct Example { let any: Any? } let example =

    Example(any: nil) if let first = Mirror(reflecting: example) .children.first { print(first.value) } ϓϩύςΟΛOJMͰॳظԽ ϓϩύςΟͷ஋ΛݟΔͱɺ
 ઌ΄ͲOJMͰॳظԽͨ͠ͷͰ
 OJMʹͳ͍ͬͯΔ "OZ ͷϓϩύςΟ͕͋ΔTUSVDU .JSSPSΛ࡞੒ͯ͠ɺTUSVDUͷ
 ϓϩύςΟͷώϯτΛೖख
  9. struct Example { let any: Any? } let example =

    Example(any: nil) if let first = Mirror(reflecting: example) .children.first { print(first.value == nil) print(first.value) } GBMTF OJMͰ΋͔֬ΊͯΈΑ͏  ͔͠͠ೖ͍ͬͯΔͷ͸OJMʜ
  10. let x: Any? = nil let wrapper: Any = x

    // WARNING: Comparing non-optional value of // type 'Any' to nil always returns false print(x == nil) ࣮͸ղઆͨ͠ྫΛίʔυʹ͢Δͱܯࠂ͕ग़Δ ʮ0QUJPOBM͡Όͳ͍஋ͱOJMΛ
 ɹൺֱͯ͠΋ৗʹGBMTFͩΑʯ 
  11. enum Example { case zero case one(key: String) case two(key1:

    String, key2: String) } 4XJGUͰ͸FOVNͷDBTFʹ෇ଐ͢Δ஋ΛఆٛͰ͖·͢ ͜ͷ෇ଐ͢Δ஋͸BTTPDJBUFEWBMVFTͱݺ͹Ε͍ͯ·͢
  12. enum Example { case one(key: String) case two(key1: String, key2:

    String) } func test() { let x1: Example = .one(key: "value") let x2: Example = .two(key1: "value1", key2: "value2") let mirror1 = Mirror(reflecting: x1) let mirror2 = Mirror(reflecting: x2) dump(mirror1.children.first!.value) dump(mirror2.children.first!.value) } ͦΕͧΕΛ.JSSPSʹ͔͚·͢ ͜͜Ͱ͸BTTPDJBUFEWBMVFTͷ
 ཁૉ਺͕ҟͳΔͭͷDBTFΛ
 ఆٛ͠·͢ BTTPDJBUFWBMVFT͸ɺ
 TUSVDUͷϓϩύςΟͱ
 ಉ͡Α͏ʹDIJMESFOͰ
 දݱ͞Ε·͢ ͦΕͧΕͷDIJMESFOΛ
 ֬ೝͯ͠Έ·͠ΐ͏
  13. enum Example { case one(key: String) case two(key1: String, key2:

    String) } func test() { let x1: Example = .one(key: "value") let x2: Example = .two(key1: "value1", key2: "value2") let mirror1 = Mirror(reflecting: x1) let mirror2 = Mirror(reflecting: x2) dump(mirror1.children.first!.value) dump(mirror2.children.first!.value) } BTTPDJBUFEWBMVFT͕
 ͭͷ৔߹ WBMVF ͭͷ৔߹
  
 LFZWBMVF 
 LFZWBMVF
  ܕ͕ҧ͏ 
  14. let y: Any = (number: 123) print(type(of: y)) ܕΛௐ΂ͯΈΔͱ
 

    *OU ຊ౰͸BTTPDJBUFEWBMVFTͷཁૉ਺͕
 ͍ͭ͘Ͱ͋ΕɺDIJMESFOͷܕ͸UVQMFʹ
 ͔ͨͬͨ͠ͷͰ͸ͱਪଌ ͔͠͠ɺཁૉ਺ͷ͚࣌ͩࣄ৘͕͋ͬͯ
 UVQMFʹͰ͖ͳ͔͔ͬͨ΋͠Εͳ͍ͷͰɺ
 ࢼ͠ʹཁૉ͕ͭͷUVQMFΛ࡞੒ͯ͠ΈΔ UVQMFͰ͸ͳ͍ 
  15. // Error: cannot create a single-element tuple with // an

    element label let x: (number: Int) = (number: 123)
 
 let y: Any = (number: 123) print(type(of: y)) // Int ࣮͸ɺ4XJGUͷܕͰ͸ཁૉ͕ͭͷUVQMF͸ఆٛͰ͖ͳ͍ ͔͠͠ɺཁૉ਺ͷUVQMFܕ͕
 ࡞Εͳ͍͚ͩͳͷͰɺܕΛ
 "OZʹͯ͠͠·͑͹ཁૉ਺ͷ
 UVQMFΒ͖͠΋ͷΛఆٛͰ͖Δ ͔͠͠ɺఆٛͰ͖ͨͱͯ͠΋ɺ
 ͦͷܕ͸ཁૉͷத਎ͷܕʹ
 ͳΔΑ͏ͩ ͭ·Γɺཁૉ਺ͷUVQMF͸
 ଘࡏͰ͖ͳ͍͜ͱ͕Θ͔Δ