Lets enjoy code reading

Cfbe23392787cb3ad4689c5f72463fcc?s=47 makicamel
January 09, 2020

Lets enjoy code reading

実例で見るコードリーディングのススメ
2020.01.09. Omotesando.rb #54 〜 コードの読み方 〜

Cfbe23392787cb3ad4689c5f72463fcc?s=128

makicamel

January 09, 2020
Tweet

Transcript

  1. ࣮ྫͰݟΔ ίʔυϦʔσΟϯάͷεεϝ 2020.1.9. Omotesando.rb #54 @makicamel

  2. •@makicamel / ઒ݪສق • •Ruby/Railsྺ3೥͘Β͍ •Ruby ͱϏʔϧɹɹͱ͓ञ͕޷͖ ࣗݾ঺հ ࠷ۙ೤͍τϐοΫ͸ ݕࡧͰ͢

  3. ಥવͰ͕͢ ໰୊Ͱ͢

  4. ݕࡧΤϯδϯ͸ͳͥݟ͚ͭΔͷ͔஌͓͖͍ͬͯͨ΢Σϒ৘ใݕࡧͷجૅ஌ࣝc৿େೋ࿠
 IUUQTXXXBNB[PODPKQݕࡧΤϯδϯ͸ͳͥݟ͚ͭΔͷ͔EQ ⇀ᄝaൗࢸᇏƎƒ≌∓ದ¸ƑದůᇾƶƊŧƮƋ࿽ ƲƯƉŧơżb
 ൗࢸᇏƑżƜƉƑದůҕࡆźƉ℧Ƅ㋆ŰŻƦƶŴƶ ն߶ƵżƮƋŰaޅ߭℧ƉƓ∱℧ƊŰƮƊźƪũ ŮĤ "߭
 # ߭


    $ ߭ ˞೥݄ݱࡏ͸໿ԯਓ
  5. ݕࡧΤϯδϯ͸ͳͥݟ͚ͭΔͷ͔஌͓͖͍ͬͯͨ΢Σϒ৘ใݕࡧͷجૅ஌ࣝc৿େೋ࿠
 IUUQTXXXBNB[PODPKQݕࡧΤϯδϯ͸ͳͥݟ͚ͭΔͷ͔EQ ⇀ᄝaൗࢸᇏƎƒ≌∓ದ¸ƑದůᇾƶƊŧƮƋ࿽ ƲƯƉŧơżb
 ൗࢸᇏƑżƜƉƑದůҕࡆźƉ℧Ƅ㋆ŰŻƦƶŴƶ ն߶ƵżƮƋŰaޅ߭℧ƉƓ∱℧ƊŰƮƊźƪũ ŮĤ "߭
 # ߭


    $ ߭ ˞೥݄ݱࡏ͸໿ԯਓ ਖ਼ղ
  6. ͔֬ΊͯΈ͍ͨ ɹ233 > 69ԯ͍ͬͯ͢͝ʂ(਺ֶͰ͖ͳ͍ਓ)

  7. ͔֬ΊͯΈ͍ͨ ɹaⁿ ͬͯ͜Μͳײ͡ʁ
 ɹ(a΋n΋0Ҏ্ͷ੔਺ͱ͢Δ) def power(a, n) result = 1

    n.times { |i| result *= a } result end power(2, 33) # => 8589934592
  8. ͔֬ΊͯΈ͍ͨ ɹRuby͞Μͷ͜ͱ͔ͩΒɺaⁿ͋ΔΜͰ͠ΐ͏ʁ

  9. ͋ͬͨ *OUFHFSΫϥεc3VCZϦϑΝϨϯεϚχϡΞϧ
 IUUQTEPDTSVCZMBOHPSHKBDMBTT*OUFHFSIUNM

  10. ͋ͬͨ 2 ** 0 # => 1 2 ** 33

    # => 8589934592
  11. ͲΜͳ࣮૷ʁ static VALUE int_pow(long x, unsigned long y) { //

    ... y &= ~1; do { while (y % 2 == 0) { if (!FIT_SQRT_LONG(x)) { VALUE v; bignum: v = rb_big_pow(rb_int2big(x), LONG2NUM(y)); if (RB_FLOAT_TYPE_P(v)) /* infinity due to overflow */ return v; if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v); return v; } x = x * x; y >>= 1; } { if (MUL_OVERFLOW_FIXNUM_P(x, z)) { goto bignum; } z = x * z; } } while (--y); if (neg) z = -z; return LONG2NUM(z); } Կ΋Θ͔Βͳ͍ OVNFSJDDSVCZSVCZc(JU)VC
 IUUQTHJUIVCDPNSVCZSVCZCMPCEBCDFFGCBBGDOVNFSJDD
  12. rubinius / rubinius •rubyͰ࣮૷͞Εͨruby SVCJOJVTSVCJOJVTc(JU)VC
 IUUQTHJUIVCDPNSVCJOJVTSVCJOJVT

  13. ͲΜͳ࣮૷ʁ DPNQMFYSCSVCJOJVTSVCJOJVTc(JU)VC
 IUUQTHJUIVCDPNSVCJOJVTSVCJOJVTCMPCFCEDBCCGEBBCBGFE DPSFDPNQMFYSC def ** (other) # ... if

    other.kind_of?(Complex) # ... elsif other.kind_of?(Integer) if other > 0 x = self z = x n = other - 1 while n != 0 while (div, mod = n.divmod(2) mod == 0) x = Complex(x.real*x.real - x.imag*x.imag, 2*x.real*x.imag) n = div end z *= x n -= 1 end z else # ... end elsif Complex.generic?(other) # ... end end ͳΜͱ͔ಡΊͦ͏
  14. def ** (other) if !other.kind_of?(Float) && other == 0 return

    Complex(1) end if other.kind_of?(Complex) # ... elsif other.kind_of?(Integer) if other > 0 x = self z = x n = other - 1 while n != 0 while (div, mod = n.divmod(2) mod == 0) x = Complex(x.real*x.real - x.imag*x.imag, 2*x.real*x.imag) n = div end z *= x n -= 1 end z else # ... end elsif Complex.generic?(other) # ... end end other͕0ͷ࣌1Λฦ͢ ࠓճ͸ॲཧͷྲྀΕΛ
 ஌Γ͍͚ͨͩͳͷͰলུ (self΋other΋ਖ਼ͷ੔਺ͷ૝ఆ)
  15. def ** (other) if !other.kind_of?(Float) && other == 0 return

    Complex(1) end if other.kind_of?(Complex) # ... elsif other.kind_of?(Integer) if other > 0 x = self z = x n = other - 1 while n != 0 while (div, mod = n.divmod(2) mod == 0) x = Complex(x.real*x.real - x.imag*x.imag, 2*x.real*x.imag) n = div end z *= x n -= 1 end z else # ... end elsif Complex.generic?(other) # ... end end ࠓճ͸ॲཧͷྲྀΕΛ
 ஌Γ͍͚ͨͩͳͷͰলུ (਺ֶͰ͖ͳ͍ਓ)
  16. def power(a, other) x = a z = x n

    = other - 1 while n != 0 while (div, mod = n.divmod(2); mod == 0) x = x * x n = div end z *= x n -= 1 end z end ͘͢͝ಡΊͦ͏ʂ ɹɹɹ Կ΋Θ͔Βͳ͍ ؆ུԽ͢Δͱ ࣮ߦ͠΍͍͢Α͏ʹselfΛaʹ͢Δ
  17. def power(a, other) x = a z = x n

    = other - 1 while n != 0 p " n: #{n}" while (div, mod = n.divmod(2); mod == 0) p x = x * x p n = div end z *= x p " z: #{z}" n -= 1 end z end ࢦ਺͕2ͷഒ਺ͷؒ ৽͍͠ࢦ਺͸n / 2 ؆ུԽ͢Δͱ x = x2Λ͚ͭͮ͠Δ
  18. None
  19. ৆❴ƑࠎЧ ྦྷ৐ͱ͸ɻͦͷҙຯͱܭࢉํ๏Λղઆʲఈɾࢦ਺ͱ͸Կ͔ʳcΞλϦϚΤʂ
 IUUQTBUBSJNBFCJ[BSDIJWFT

  20. def power(a, other) x = a z = x n

    = other - 1 while n != 0 p " n: #{n}" while (div, mod = n.divmod(2); mod == 0) p x = x * x p n = div end z *= x p " z: #{z}" n -= 1 end z end ྦྷ৐ ࢦ਺͕ۮ਺ͷؒ ࢦ਺͕ح਺ʹͳͬͨΒ
 zʹྦྷ৐ͨ͠xΛֻ͚Δ (((x2)2)2…͠ଓ͚Δ
  21. def power(a, other) x = a z = x n

    = other - 1 while n != 0 p " n: #{n}" while (div, mod = n.divmod(2); mod == 0) p x = x * x p n = div end z *= x p " z: #{z}" n -= 1 end z end ྦྷ৐ a = 3, other = 3ͷ৔߹( 33 ) n(ࢦ਺) = 2 div = 1, mod = 0 n = 1 z = 3 * 9 = 27
 n = 0 x = 3 * 3 = 9
  22. ͭ·Γ •33 = 3 * 32 •34 = 3 *

    33
 = 3 * 3 * 32 35 = 3 * 34
 = 3 * (32)2
 ఈΛऔΓग़͢ ࢦ਺Λ1 + nʹ෼͚Δ
  23. ͭ·Γ •33 = 3 * 32 •35 = 3 *

    34
 = 3 * (32)2 35 = 3 * 34
 = 3 * (32)2
 ෼͚ΒΕͨࢦ਺͕2nͰׂΓ͖ΕΔؒ
 ࢦ਺Λ2ͰׂΓଓ͚͍ͯ͘
  24. ͭ·Γ •33 = 3 * 32 •35 = 3 *

    34
 = 3 * (32)2 35 = 3 * 34
 = 3 * (32)2
 ෼͚ΒΕͨࢦ਺͕2nͰׂΓ͖ΕΔؒ
 ࢦ਺Λ2ͰׂΓଓ͚͍ͯ͘
  25. ͭ·Γ •33 = 3 * 32 •35 = 3 *

    34
 = 3 * (32)2 •37 = 3 * 36
 = 3 * (32)2 * 3
 ෼͚ΒΕͨࢦ਺͕2nͰׂΓ੾Εͳ͘ͳΔͱ
 ఈΛ෼͚Δ
  26. Θͨ͠ͷ࣮૷ • def power(a, n) result = 1 n.times {

    |i| result *= a } result end power(2, 33) # => 8589934592 •n.times {} ͩͱ୯७ʹnճܭࢉ͢Δ
 233 = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 *
 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 *
 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 *
 2 * 2 * 2
  27. rubyͷ࣮૷ • def power(a, other) x = a z =

    x n = other - 1 while n != 0 while (div, mod = n.divmod(2); mod == 0) x *= x n = div end z *= x n -= 1 end z end •ࢦ਺Λ2Ͱׂ͍ͬͯ͘ͱܭࢉճ਺͕૿͑ͳ͍
  28. •ࢦ਺Λ2Ͱׂ͍ͬͯ͘ͱܭࢉճ਺͕૿͑ͳ͍
 233 = 2 * 232
 = 2 * ((((22)2)2)2)2

    rubyͷ࣮૷ Θͨ͠ͷ࣮૷ •233 = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 *
 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 *
 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 *
 2 * 2 * 2 ͍͢͝ݮͬͨʂ
  29. •ϏοτɾόΠτͬͯ2nͩ͠
 ΋͔ͯ͠͠ྦྷ৐ͬͯΊͬͪΌ࢖ΘΕͯͦ͏ •ܭࢉྔݮΒͨ͢Ίʹ͜͏͍͏࣮૷ͳͷ͔ͳ͋

  30. ΍͍ͬͯΔ͜ͱ •໨తΛ໌֬ʹ͢Δ •ແཧ͠ͳ͍ •͍ͭͰ΋ಡΊΔ؀ڥΛ࡞Δ ίʔυϦʔσΟϯά
 ͢Δ্Ͱ

  31. ໨తΛ໌֬ʹ͢Δ •໨తʹΑͬͯಡΉৄ͠͞΍ಡΈํ͕มΘΔ •ϝιουͷਖ਼֬ͳڍಈΛ஌Γ͍ͨ •ӨڹൣғΛ஌Γ͍ͨ •ྺ࢙తܦҢͷ֬ೝ •ϝιουͷུ֓ͷ֬ೝ •ύονΛૹΓ͍ͨ •޷ح৺ɾ஌Γ͍͔ͨΒɾָ͍͔͠Β΋΋ͪΖΜ͋Δ ɹnonzero? ͬͯ


    ɹͲ͏͍͏ڍಈ͚ͩͬʁ ɹ͜ͷม਺มߋ͍͍ͯ͠Μ͚ͩͬʁ ɹͳΜͰ͜ͷ࣮૷ʹͳͬͯΔͷʁ ɹԿͷΠϯελϯεฦ͢ͷʁ ɹ
  32. ໨తΛ໌֬ʹ͢Δ •ࠓճͷ໨త͸ʮruby͕ߟྀ͍ͯ͠Δ͜ͱΛ஌Δ͜ͱʯ •ΞϧΰϦζϜͷཧղ͸෭࣍తͳ໨త •ࣗ෼Ͱ΋࣮૷͸Ͱ͖Δ •Α͍ίʔυ͔͸ •Կ͕ߟྀ͞ΕΔͱΑ͍ίʔυͳͷ͔ʁ •rubyͷίʔυ͸Α͍͓खຊ(ͨͿΜ) ͨ͘͞Μͷਓ͕࢖͏͔Β
 ࢥ͍͔ͭͳ͍͜ͱ͕
 ߟྀ͞Εͯͦ͏

  33. ໨తΛ໌֬ʹ͢Δ •ࠓճͷֶͼ •ܭࢉྔͬͯ͜͏͍͏෩ʹݮΒͤΔɾݮΔͷΛ࣮ײͨ͠ •(DBΞΫηεҎ֎Ͱܭࢉྔ·͡Ίʹߟ͑ͨ͜ͱ͋·Γͳ͍) •ͨͿΜྦྷ৐(΂͖৐)ͬͯසग़ϝιου •ຊମଆͰܭࢉྔݮΒ͢ͷେࣄ •਺ֶษڧ͠Α͏ͳɻɻɻ •஌Βͳ͔ͬͨϝιου΍จ๏Λ஌ͬͨ

  34. ̤̤ΤϯδχΞͷྠʂʙୈճਢ౻ޭฏ͞ΜͷרʙcΦϒδΣΫτͷ޿৔
 IUUQTXXXPHJTSJDPKQPUDIJSPCBPUIFST003JOHJOUFSWJFXIUNM ǿƺǬǿȀƋŮƵ൐ũƋŰƎaǟǃǻǷȉǞƵ䪎ơ ƍŰƦŧŧƶŻƦƍŧŮƍƋනŧơżb
 ൐ŧٚůƲŮƶƍŮƆƂƬǓ✣Ǐ䪎ƶƊ൐ŧٚƵƲ ŮƯƓŧŧb
 ƀƑℭƒሱٳƊŶũŧũἀƎ൐ŧƂŧƆƉŧũଢ֥ ťƮƑƊaŶũŧũἀƎႄඔ؈žƓũơŲọŲƍƆ ƉŧũƑƵсေƎ௧ƬƯƉ䪎ƣƋනũƶƊżƫb
 


    ƀƯůaଢ֥ƵӻƆƉ䪎ƣŶƋƎ
 ƍƮƶŻƦƍŧŮƋනŧơżb
  35. ແཧ͠ͳ͍ •ಡΈ͍ͨ/ಡΉ΂͖ίʔυ͸ແݶʹ͋Δ •࣌ؒ͸༗ݶ •શ෦ཧղͰ͖ͳͯ͘΋OK •໨తୡ੒ͨ͠Βऴྃ •ʮԿ΋Θ͔Βͳ͍ʯ࣌͸ܿ͘ఘΊΔ
 ͍͔ͭಡΊΔΑ͏ʹͳΔ೔͕དྷΔ •ͳΜ͔ͩΜͩۙ͘ͷίʔυ΋ݟͯΔͷͰษڧʹͳͬͯΔ

  36. •bundle install —path vendor/bundle && rm .bundle/config •gem-src •source_location(rubyͷϝιουఆٛΛݺ΂Δ) •pry

    + pry-doc(`$`Ͱcͷϝιουఆٛ΋ݺ΂Δ) •RubyMine •OctTree ͍ͭͰ΋ಡΊΔ؀ڥΛ࡞Δ
  37. ίʔυϦʔσΟϯά͸͍͍ͧ ·ͱΊ

  38. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠