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

Road to white mages

Road to white mages

Tama Ruby会議01
白魔術士への道
2019.7.6
https://tama-rb.github.io/tamarubykaigi01/

Kuniaki IGARASHI

July 06, 2019
Tweet

More Decks by Kuniaki IGARASHI

Other Decks in Programming

Transcript

  1. നຐज़ࢣ΁ͷಓ
    Road to white mages
    Tama Rubyձٞ01
    2019೥7݄6೔
    ޒेཛྷ๜໌ / igaiga
    twitter: @igaiga555

    View Slide

  2. ࣗݾ঺հ
    • ϑϦʔϥϯεRails/RubyΤϯδχΞ
    • ஶॻ

    Ruby௒ೖ໳

    RailsͷڭՊॻ

    RubyͱRailsͷֶशΨΠυ

    View Slide

  3. ࠓճͷํ਑
    • ґཔʮجௐߨԋͰ͕͢ςΫ͍࿩Ͱ͓ئ͍͠·͢ʯ
    • ຊձٞͷςʔϚ͸ʮ੒௕ʯ
    • ڵຯ͋Δ͜ͱΛௐ΂ͯൃද͍ͨ͠ͱࢥͬͨ
    • ࢲ΋3ϲ݄લʹ͸஌Βͳ͔ͬͨ͜ͱ͹͔Γ࿩͠·͢

    Ruby௒ೖ໳ͳͲஶॻͷ࿩͸͋·Γ͠·ͤΜ
    • ସΘΓʹॻ੶Ͱઆ໌ͨ͠಺༰ʹ ϚʔΫ෇͚·ͨ͠

    View Slide

  4. લஔ͖
    • ʮޙੈͷྺ࢙Ոʯͱʮ࠷લઢͷ༐ऀʯͷޠΔ࿩͸ҧ͏

    Ruby௒ೖ໳͸ʮޙੈͷྺ࢙Ոʯ
    • ಓ͕ఆ·Γɺܦ࿏Λ৽ͨʹઃܭͯ͠આ໌
    • ࠓ೔ͷ࿩͸ʮ࠷લઢͷ༐ऀʯ
    • Ͳͷಓ͕ྑ͍͔Λ໛ࡧ͢Δ
    • ௐ΂ํ΍೰ΜͩλΠϛϯά΋͓఻͑͠·͢

    View Slide

  5. ϓϩϩʔά

    View Slide

  6. ຐज़ͱ͸Կ͔ʁ
    matz ʮຐज़ʹ͸2छྨ͋Δɻྑ͍͜ͱΛ͢Δനຐज़ͱɺݏͳ͜ͱΛ͢Δࠇຐज़ͩɻʯ
    ࡢࠓͷRubyքͰͷຐज़ͷఆٛ
    ʮʢҰݟແཧͳʣ΍Γ͍ͨ͜ͱΛɺखஈΛ໰Θ࣮ͣݱ͢Δ͜ͱʯ
    ※ࢲͷҙݟͰ͢
    • ॻ੶ʮϝλϓϩάϥϛϯάRubyʯ
    • ຐज़ͱ͸
    • ϝλϓϩάϥϛϯάͷٕ๏
    • ϝλϓϩάϥϛϯάͱ͸
    • ίʔυΛهड़͢ΔίʔυΛهड़͢Δ͜ͱ
    • ݴޠཁૉΛ࣮ߦ࣌ʹૢ࡞͢ΔίʔυΛهड़͢Δ͜ͱ

    View Slide

  7. RubyքͷҒେͳࠇຐज़ࢣ2ਓ
    RubyKaigi2018
    joker1007, Satoshi "moris" Tagomori tagomoris
    https://youtu.be/04HGQEw3A6Y
    ҒେʹͳΔͱ
    ίϛολʔʹ໨Λ෇͚ΒΕΔ

    View Slide

  8. ຐज़Ͱ࢖ΘΕ͕ͪͳಓ۩
    ͨͱ͑͹ TracePointʢ૊ΈࠐΈϥΠϒϥϦʣ
    ԿΒ͔ͷίʔυ࣮ߦΛτϦΨʔʹॲཧΛڬΉػೳ
    TracePointΛ࢖͓͏ͱ͢ΔͱΈΜͳʹ৺഑͞ΕΔ

    View Slide

  9. ͳͥTracePoint Λ࢖͏ͱ͋Ϳͳ͍ͷ͔ʁ
    ॳา͔Βઆ໌͞ΕΔػձ͸͋·Γͳ͍
    ͳͥRubyKaigi LTͰʮTracePoint Bomb!ʯͱ͍
    ͏λΠτϧ͕ग़͚ͨͩͰΈΜͳരস͢Δͷ͔
    ࠇຐज़͸ڧྗ͕ͩҙਤ͠ͳ͍ಈ࡞΋Ҿ͖ى͜͢Մೳੑ͕͋Δ
    • TracePoint͸ϩʔΧϧม਺Λ্ॻ͖Ͱ͖Δ
    • ͜ͷ্ॻ͖Λ໭͠๨ΕΔϧʔτ͕9ϲ݄ޙ൑໌
    • ૝ఆ͠ͳ͍޿͍ൣғͰϩʔΧϧม਺্͕ॻ͖
    • ͦͷόά͕ൃݟ͞Εͨͱ͖ͷք۾ͷ༷ࢠ
    https://speakerdeck.com/koic/the-tracepoint-bumb

    View Slide

  10. Ғେͳࠇຐज़ࢣ͕Ғେͳཧ༝
    Ғେͳཧ༝͸஥ؒΛकΔຐ๏΋࢖͑Δ͔Β
    ࠇຐज़͸࣌ͱͯ͠ڧେ͗͢ΔྗΛ੍ޚͰ͖ͳ͘ͳΔ
    ख़࿅ͷࠇຐज़ࢣͨͪ͸ຐज़Λ੍ޚ͢Δྗʹ௕͚͍ͯΔ
    ࠇຐज़͸ద੾ʹ͔ͭΘͳ͚Ε͹ͳΒͳ͍
    ࣮͸੍ޚ͢Δํ͕೉͍͜͠ͱ΋ଟ͍
    ͔͠͠ڧେͳྗ͸ັྗతͰ͋Δ
    †Rubyࠇຐज़ܦయ†
    https://speakerdeck.com/joker1007/rubyhei-mo-shu-jing-dian
    ࠇຐज़ʹ͓͍ͯकΔ΂͖ϧʔϧ
    • ૊ΈࠐΈΫϥεΛյ͞ͳ͍
    • ελοΫΛ௥͑ΔΑ͏ʹ͢Δ
    • ύϑΥʔϚϯεΛҙࣝ͢Δ
    • TracePointͷར༻͸໌ࣔతʹ

    View Slide

  11. നຐज़ͱࠇຐज़
    σόοάʹ࢖͏ຐज़ΛຊൃදͰ͸നຐज़ͱݺͿ
    ·ͣ͸ຐज़ΛproductionίʔυʹೖΕͳ
    ͍ܗͰ࢖ͬͯΈΔͷ͸Ͳ͏͔
    productionίʔυʹೖΕͳ͚Ε͹ةͳ͍ίʔυ΋ؾܰʹॻ͚Δ
    ͨͱ͑͹σόοά
    σόοάʹ࢖͏ຐज़ΛຊൃදͰ͸നຐज़ͱݺͿ͜ͱʹ͠·͢
    ࠇຐज़ʢࠇຐ๏ʣ: ϓϩάϥϜͰՁ஋Λ֫ಘ͢ΔͨΊͷຐज़
    നຐज़ʢനຐ๏ʣ: ϓϩάϥϜͷইΛ༊΍͢ຐज़

    View Slide

  12. ࠓ೔ͷߏ੒
    • നຐज़جૅߨ࠲ʮΦϒδΣΫτͱձ࿩͢Δʯ
    • നຐज़ೖ໳ ʮ౪·ΕͨΠϯελϯεม਺ʯฤ
    • നຐज़֓࿦ ͦͷଞͷനຐज़
    ⏰5

    View Slide

  13. നຐज़جૅߨ࠲
    ʮΦϒδΣΫτͱձ࿩͢Δʯ
    • RubyͷΦϒδΣΫτ͸৭ʑͳ͜ͱΛڭ͑ͯ͘ΕΔ
    • RubyੈքͷΦϒδΣΫτͨͪͷؾ࣋ͪΛ஌Δ
    • ΦϒδΣΫτͨͪΛઆಘͯ͠ঢ়ଶΛม͑ͯ΋Β͏

    View Slide

  14. σόοΨͷ࢖͍ํ
    ϓϩάϥϜΛ࣮ߦ్தͰҰ࣌ఀࢭͯ͠ϓϩάϥϜΛ࣮ߦ͢Δ
    • binding.irb Ruby௒ೖ໳ P.62
    • pry gem Ruby௒ೖ໳ P.241
    • binding.pry
    • step ࣮ߦ pry-byebug gem
    • ιʔεදࣔ pry-doc gem
    • pry on
    • $ prying=true rspec spec/a_spec.rb
    • pry off
    • $ rspec spec/a_spec.rb
    ifͰON/OFF͢Δͱָ
    ؀ڥม਺ͰON/OFF͢Δͱָ

    View Slide

  15. ͋ͳͨ͸୭Ͱ͔͢ʁ
    ΦϒδΣΫτΛ஌Δ
    • class ϝιου Ruby௒ೖ໳ P.178
    • ΦϒδΣΫτͷΫϥεΛ஌Δ
    • object_id ϝιου Ruby௒ೖ໳ P.128, 269
    • ΦϒδΣΫτͷࣝผ൪߸Λ஌Δ
    Integer Float String
    Hash
    2 1.2 "abc"
    {coffee: 300,
    caffe_latte: 400}

    View Slide

  16. ͲΜͳΦϒδΣΫτ͕͋Γ·͔͢ʁ
    ΦϒδΣΫτքΛѻ͏ObjectSpace
    • ObjectSpace
    • ΦϒδΣΫτքΛѻ͏૊ΈࠐΈϥΠϒϥϦͷϞδϡʔϧ
    • ObjectSpace.each_object(klass)
    • Ҿ਺ʹࢦఆͨ͠ΫϥεͷΠϯελϯεΦϒδΣΫτΛಘΔ
    • ΫϥεҰཡΛऔಘ: ObjectSpace.each_object(Class)
    • ObjectSpace.count_objects
    • ΦϒδΣΫτΛछྨ͝ͱʹΧ΢ϯτ

    View Slide

  17. ͲΜͳϝιου͕࢖͑·͔͢ʁ
    ݺͼग़ͤΔϝιουΛ஌Δ
    • methods ϝιου Ruby௒ೖ໳ P.189
    • ΦϒδΣΫτ͕ݺͼग़ͤΔϝιουΛ஌Δ
    •Array.methods
    • ΫϥεϝιουΛௐ΂Δ
    •[].methods
    • ΠϯελϯεϝιουΛௐ΂Δ

    View Slide

  18. ͋ͳͨ͸Ͳ͔͜Βདྷ·͔ͨ͠ʁ
    ιʔείʔυฤ
    • Object#method, Module#instance_method
    • MethodΦϒδΣΫτऔಘ
    • MethodΦϒδΣΫτͰ࢖͑Δϝιου
    • source_location: ఆٛ͞Ε͍ͯΔϑΝΠϧ
    • owner: ఆٛ͞Ε͍ͯΔΫϥε
    • parameters: Ҿ਺৘ใ
    method(:pp).source_location
    #=> ["/Users/igaiga/.rbenv/versions/2.6.2/lib/ruby/2.6.0/pp.rb", 582]
    method(:pp).owner
    #=> Kernel
    require "time"
    Time.instance_method(:httpdate).source_location
    #=> ["/Users/igaiga/.rbenv/versions/2.6.2/lib/ruby/2.6.0/time.rb", 691]
    Time.instance_method(:succ).source_location
    #=> nil # RubyͰॻ͔Ε͍ͯͳ͍ωΠςΟϒͳϝιου͸nil

    View Slide

  19. ͋ͳͨ͸Ͳ͔͜Βདྷ·͔ͨ͠ʁ
    gemฤ
    • gemιʔείʔυ͕ஔ͍ͯ͋Δ৔ॴ
    • gem which
    • bundle show
    • bundle open
    • ࢦఆ͞ΕͨΤσΟλͰ։͘
    • ؀ڥม਺ EDITOR or BUNDLER_EDITOR Ͱࢦఆ

    View Slide

  20. ͋ͳͨ͸Ͳ͔͜Βདྷ·͔ͨ͠ʁ
    ݺͼग़͠ݩฤ
    • Kernel#caller
    • ϝιουݺͼग़͠ཤྺΛදࣔ
    • Kernel#caller_locations
    • callerͷ݁ՌΛ Thread::Backtrace::LocationͰऔಘ
    • Exception#backtrace
    • ͦͷException͕raise͞Εͨͱ͖ͷϝιουݺͼग़͠ཤྺΛදࣔ

    View Slide

  21. ΦϒδΣΫτΛมߋ͢Δ
    ͍͍ͩͨͷ͜ͱ͸Ͱ͖Δ
    • instance_variables Ruby௒ೖ໳ P.198
    • Πϯελϯεม਺ҰཡΛऔಘ
    • instance_variable_get, instance_variable_set
    • Πϯελϯεม਺Λऔಘɺվ͟Μ
    • instance_eval, class_eval
    • ͦͷΦϒδΣΫτʹͳΓ͖࣮ͬͯߦ͢Δ
    • Πϯελϯεม਺Λ͍͡Δͱ͖ʹ΋ศར
    • privateϝιουΛݺͼग़͢ͱ͖ʹ΋ศར
    • sendϝιουΛ࢖͏ख΋͋Δ
    • bindingΛ࢖͏ͱϩʔΧϧม਺ΛมߋͰ͖Δ
    • લड़ͷ joker&moris ߨԋࢀর

    View Slide

  22. ιʔείʔυͷੈքɺΦϒδΣΫτͷੈք
    σόοά͕೉͍͠ͷ͸2ͭͷੈքʹִͨΓ͕͋Δ͔Β
    • ԋܶͰྫ͑Δͱ
    • ιʔείʔυ͸୆ຊ
    • ࢲ͕ͨͪॻ͚Δͷ͸୆ຊ
    • ΦϒδΣΫτͷੈք͸෣୆
    • ࣮ࡍʹϓϩάϥϜ͕ಈ͍͍ͯΔͷ͸͜͜
    • ࢲͨͪ͸͜͜Ͱࣗ෼͕ԋ͡Δ͜ͱ΋ɺ؍Δ͜ͱ΋Ͱ͖ͳ͍
    ΦϒδΣΫτͷੈք ➡
    ιʔείʔυͷੈք ➡ p 1+2
    1
    +
    2

    View Slide

  23. ιʔείʔυͷੈքɺΦϒδΣΫτͷੈք
    ม਺͸ΦϒδΣΫτͷ໊ࡳɺ໊લॏཁ Ruby௒ೖ໳ P.53
    ม਺orderʹ "ΧϑΣϥς" ΦϒδΣΫτΛ୅ೖ
    ʹ "ΧϑΣϥς" ΦϒδΣΫτʹ
    ม਺orderͱ͍͏໊લΛ෇͚Δ
    "ΧϑΣϥς"
    PSEFS
    ʮ໊લʯ͸ιʔείʔυͷੈք͔ΒΦϒδΣΫτͷੈքʹ͍
    ΔʮͦͷΦϒδΣΫτʯΛݺͿʢ΄΅ʣ།Ұͷ࢓૊Έ
    ΦϒδΣΫτͷੈք ➡
    ιʔείʔυͷੈք ➡
    ༷ʑͳखஈͰΦϒδΣΫτͷੈքʢ෣୆ʣͷ༷ࢠΛ
    ஌Δํ๏Λ͜ͷ͋ͱઆ໌͍͖ͯ͠·͢ɻ

    View Slide

  24. നຐज़جૅߨ࠲ʮΦϒδΣΫτ
    ͱձ࿩͢Δʯ·ͱΊ
    • ΦϒδΣΫτͱͷձ࿩ʹΑͬͯ͞·͟·ͳ৘ใ
    ͕ಘΒΕΔ
    • ΦϒδΣΫτͷঢ়ଶΛมߋ͢Δ͜ͱ΋Ͱ͖Δ
    • ΦϒδΣΫτͷੈքɺιʔείʔυͷੈքʹ͸
    ִͨΓ͕͋Δ

    View Slide

  25. നຐज़ೖ໳
    ʮ౪·ΕͨΠϯελϯεม਺ʯฤ
    ⏰12

    View Slide

  26. ʮ΍ͭ͸େมͳ΋ͷΛ౪ΜͰ͍͖·ͨ͠ɻ
    ͋ͳͨͷΠϯελϯεม਺Ͱ͢ɻʯ
    • ͪͳΈʹάϩʔόϧม਺͸ Kernel#trace_var ͕͋Δ
    • Πϯελϯεม਺͸ΦϒδΣΫτͰ͸ͳ͍
    • ίʔυ: https://github.com/igaiga/tmrk01/
    ୊ࡐɿʮRailsͷCRUD indexΞΫγϣϯͰɺ@books Πϯε
    λϯεม਺͕ [] ʹͳ͍ͬͯͯදࣔ಺༰͕ҙਤ௨ΓͰ͸ͳ͍ʯ
    ਖ਼͍͠ಈ࡞
    ʮΠϯελϯεม਺΁ͷ୅ೖΛݕ஌͢Δʯํ๏Λߟ͑Δ
    ݱঢ়ͷಈ࡞

    View Slide

  27. TracePoint
    Կ͔Λ͖͔͚ͬʹॲཧΛڬΉ
    ࣮ߦ͢ΔϒϩοΫΛొ࿥
    ͓ͯ͘͠ͱಛఆτϦΨʔͰ
    ϒϩοΫΛ࣮ߦͯ͘͠ΕΔ
    https://docs.ruby-lang.org/ja/latest/class/TracePoint.html
    ओͳτϦΨʔ
    • :line ࣜͷධՁ
    • :call Rubyϝιουͷ࣮ߦ
    • :c_call Cϝιουͷ࣮ߦ
    • :b_call ϒϩοΫ࣮ߦ
    • :raise ྫ֎ൃੜ ⬆ p tpͷ݁Ռ

    View Slide

  28. Πϯελϯεม਺΁ͷ୅ೖΛݕ஌͢Δ
    ४උ
    ࠷ॳʹখ͞ͳίʔυ͔Βߟ͑
    ·͢ɻ
    λʔήοτʹͳΔίʔυ ➡
    @hi ΁ͷ୅ೖΛݕ஌͢Δ
    ͷ͕໨ඪͰ͢ɻ
    ※ͨͩ͠grep͸ߟྀ͠ͳ͍΋
    ͷͱ͢Δɻ
    ⬆ @hi΁ͷ୅ೖΛݕ஌͍ͨ͠

    View Slide

  29. TracePoint
    TracePointΛ͔͚ͯ͠શͯͷࣜධՁʹॲཧΛڬΉ
    TracePoint.trace ʹ :line Λ౉͢ͱɺࣜධՁ࣌ʹϒϩοΫ࣮ߦ
    ϒϩοΫͷม਺tpͰड͚औΔTracePointΦϒδΣΫτ͔Β৘ใऔಘ
    tp.methods ΍ΔΓ·Ͱ͍࣋ͬͯΔϝιουΛௐ΂Δ P.123
    • event
    • τϦΨʔ
    • path
    • ιʔεύε
    • lineno
    • ߦ൪߸
    • method_id
    • ϝιου
    • defined_class
    • Ϋϥε
    ↙ [TP:line] test.rb:3 hi User
    ⬆ TracePointΦϒδΣΫτͷ৘ใදࣔ
    ⬅ @hi ΁୅ೖ 3ߦ໨ User#hi
    ⬇ |tp| TracePointΦϒδΣΫτ

    View Slide

  30. TracePoint
    શͯͷࣜධՁͷத͔Β໨తͷߦΛ୳͠ग़͢
    ࣜධՁ࣌ʹϒϩοΫ࣮ߦ͸Ͱ͖ͨ
    ࠓͷ··ͩͱશͯͷࣜͰϒϩοΫ͕࣮ߦ͞ΕΔ
    ͦͷத͔ΒΠϯελϯεม਺୅ೖΛݕ஌Ͱ͖ͳ͍͔ʁ
    ࣍ͷίʔυ͔ΒUserΫϥε͸লུ
    ͜͜Ͱ
    1िؒ೰Μͩ
    ͋ͱͰ࡫ా͞Μ
    ʹ΋ฉ͍ͨ

    View Slide

  31. TracePoint
    ࣜͷݩʹͳͬͨιʔείʔυΛಘΔ
    TracePointΦϒδΣΫτʹ͸ιʔείʔυ৘ใ͕ͳ͍
    ධՁ͞Εͨࣜͷ path, lineno ͸෼͔Δ
    ➡ path, lineno ͔ΒιʔείʔυΛऔΕͦ͏
    " @hi = \"hi(ŇŋωŋŇ)ϊ\"\n"
    ιʔείʔυτϨλ
    ⬆ ιʔεϑΝΠϧ͔Βιʔείʔυऔಘ

    View Slide

  32. औಘίʔυ: " @hi = \"hi(ŇŋωŋŇ)ϊ\"\n"
    ࣍͸͜ͷίʔυ͕ԿΛ͍ͯ͠Δͷ͔஌Γ͍ͨ
    " @hi = \"hi(ŇŋωŋŇ)ϊ\"\n"
    ιʔείʔυτϨλ

    View Slide

  33. RubyVM::AbstractSyntaxTree
    ίʔυ͔ΒASTΛಘΔ
    RubyVM::AbstractSyntaxTree.parseΛ࢖͏ͱίʔυ͕ԿΛ
    ͢Δ΋ͷͳͷ͔ͷ৘ใΛಘΒΕΔ
    ↖ RubyVM::AbstractSyntaxTree.parse(" @hi = \"hi(ŇŋωŋŇ)ϊ\"\n")
    ↙ #

    View Slide

  34. RubyVM::AbstractSyntaxTree
    AbstractSyntaxTree(AST)ͬͯԿʁ
    Rubyͷίʔυ͕࣮ߦ͞ΕΔ·ͰͷྲྀΕ
    Rubyͷίʔυղੳͷʮ੩ʯͱʮಈʯ ۄد मҰ
    https://speakerdeck.com/siman/railsdm2019?slide=6
    AST
    RubyVM::AbstractSyntaxTree.parse
    ΦϒδΣΫτͷੈք
    ίʔυͷੈք
    Rubyͷ͘͠Έ https://tatsu-zine.com/books/ruby-under-a-microscope-ja
    iSeq୳๚ https://booth.pm/ja/items/834594

    View Slide

  35. node.methodsͰ࣋ͬͯΔϝιουΛ୳ͯ͠ௐ΂Δ P.189
    node #=> (SCOPE@1:0-1:33 tbl: [] args: nil
    body: (IASGN@1:4-1:33 :@hi (STR@1:10-1:33 "hi(ŇŋωŋŇ)ϊ")))
    node.class #=> RubyVM::AbstractSyntaxTree::Node
    node.type #=> :SCOPE
    node.children #=> [[], nil, (IASGN@1:4-1:33 :@hi (STR@1:10-1:33 "hi(ŇŋωŋŇ)ϊ"))]
    node.children.last.class #=> RubyVM::AbstractSyntaxTree::Node
    node.children.last.type #=> :IASGN
    RubyVM::AbstractSyntaxTree.parse(" @hi = \"hi(ŇŋωŋŇ)ϊ\"\n")
    RubyVM::AbstractSyntaxTree
    AST::NodeΦϒδΣΫτͷߏ଄
    RubyVM::AbstractSyntaxTree::NodeΦϒδΣΫτ͕ੵ૚

    View Slide

  36. node.children.last #=> (IASGN@1:4-1:33 :@hi (STR@1:10-1:33 "hi(ŇŋωŋŇ)ϊ"))
    node.children.last.type #=> :IASGN
    RubyVM::AbstractSyntaxTree.parse(" @hi = \"hi(ŇŋωŋŇ)ϊ\"\n")
    RubyVM::AbstractSyntaxTree
    AST::NodeΦϒδΣΫτͷߏ଄
    IASGNΛRubyͷιʔείʔυͳͲͰௐ΂ͯΈΔ
    IASGN #=> Πϯελϯεม਺΁ͷ୅ೖ
    RubyVM::AbstractSyntaxTree::Node ৄࡉ - siman
    https://qiita.com/siman/items/3017ed399ded43229189

    View Slide

  37. RubyVM::AbstractSyntaxTree
    AST::Node৘ใ͔ΒΠϯελϯεม਺୅ೖΛݕ஌
    ݱঢ়͸શͯͷΠϯελϯεม਺୅ೖΛݕ஌͍ͯ͠Δ
    ࣍͸ࢦఆͨ͠Πϯελϯεม਺୅ೖ͚ͩΛݕ஌͍ͨ͠
    ⬅ next unless node.type == :IASGN
    ⬅ ݕ஌Ͱ͖ͨ (ʆɾωɾ´)b

    View Slide

  38. TracePoint
    ࢦఆΫϥεͷΠϯελϯεม਺୅ೖΛݕ஌
    tp.self : ΠϕϯτΛൃੜͤͨ͞ΦϒδΣΫτ
    tp.self.is_a?(Ϋϥε) ͰࢦఆΫϥε͔Ͳ͏͔νΣοΫ
    ↙ Kernel.const_get(target_class_name)
    "User" Λ UserΫϥε΁
    ※tp.self͸ʮͲͷΫϥεͰ࣮ߦ͞Ε͍ͯΔॲཧ͔ʯͳͷͰɺincludeͨ͠ModuleͰ୅ೖͯ͠
    ͍Δέʔε΋໰୊ͳ͘ಈ͘ɻΫϥε֎ͰΠϯελϯεม਺୅ೖʢՄೳʁʣ͢Δͱμϝ͔΋ɻ
    ⬅ is_a? ϝιουͰͦͷΫϥε͔൑ఆ

    View Slide

  39. TracePoint
    ࢦఆΫϥεɺࢦఆ໊ͷΠϯελϯεม਺୅ೖΛݕ஌
    Πϯελϯεม਺໊Λࢦఆͯ͠ݕ஌
    ⬇ AST nodeͷதʹΠϯελϯεม਺໊͕͋Δ

    View Slide

  40. Πϯελϯεม਺୅ೖݕ஌
    ׬੒൛
    Ͱ͖ͨʂ(ʆɾωɾ´)b

    View Slide

  41. ʮ΍ͭ͸େมͳ΋ͷΛ౪ΜͰ͍͖·ͨ͠ɻ
    ͋ͳͨͷΠϯελϯεม਺Ͱ͢ɻʯ
    ୊ࡐɿʮRailsͷCRUD indexΞΫγϣϯͰɺ@books Πϯελ
    ϯεม਺͕ [] ʹͳ͍ͬͯͯදࣔ಺༰͕ҙਤ௨ΓͰ͸ͳ͍ʯ
    ਖ਼͍͠ಈ࡞
    ݱঢ়ͷಈ࡞
    ͜ͷΞϓϦʹରͯ͠Πϯελϯε୅ೖݕ஌Λ͔͚ͯ͠ΈΔ

    View Slide

  42. RailsΞϓϦͷ४උ
    • ୊ࡐ: ʮRailsͷڭՊॻʯͰ࡞͍ͬͯΔΞϓϦ
    • https://tatsu-zine.com/books/rails-textbook
    • ॻ੶؅ཧΞϓϦ
    • BookϞσϧ(title, memo)ͷCRUD
    • rails g scaffold book title:string memo:text
    • https://github.com/igaiga/tmrk01/missing_instance_variables_sample_rails_app
    • config/initializers ҎԼʹݕ஌ίʔυ഑ஔʢ࣍ϖʔδઆ໌)
    • /books ΁ΞΫηε(indexΞΫγϣϯ)
    • app/views/books/index.html.erb
    • <% @books.each do |book| %> ⬅ ୅ೖݕ஌ର৅ @books
    • app/controllers/books_controller.rb:7 Ͱ୅ೖ͞Ε͍ͯΔ
    • @books = Book.all ⬅ @books ୅ೖίʔυ

    View Slide

  43. Πϯελϯεม਺୅ೖݕ஌
    config/initializers ΁ݕ஌ίʔυ഑ஔ
    ίϯτϩʔϥͰ୅ೖ͞ΕͯΔ͍Δ৔߹
    શͯͷΫϥεͰͷ࣮ߦΛௐ΂ΔͨΊ
    Ϋϥε໊͸ࢦఆͤͣʹ
    Πϯελϯεม਺໊͚ͩࢦఆ
    Started GET "/books" for ::1 at 2019-06-08 12:34:50 +0900
    Processing by BooksController#index as HTML
    @books is assigned in /path_to_app/app/controllers/books_controller.rb:7 index BooksController
    Rendering books/index.html.erb within layouts/application
    Book Load (6.8ms) SELECT "books".* FROM "books"
    ↳ app/views/books/index.html.erb:15
    Rendered books/index.html.erb within layouts/application (249.2ms)
    Completed 200 OK in 2933ms (Views: 2800.7ms | ActiveRecord: 6.8ms)
    /books ΁ΞΫηεͨ͠ϩά
    ൜ਓ͕͍ͳ͍ૉͷίʔυͰςετ
    ⬇ίϯτϩʔϥͰͷਖ਼ৗ୅ೖݕ஌੒ޭ
    @books ୅ೖݕ஌ίʔυ

    View Slide

  44. Πϯελϯεม਺୅ೖݕ஌
    ίϯτϩʔϥʹ൜ਓ͕͍ͨέʔε
    Started GET "/books" for ::1 at 2019-06-08 13:02:25 +0900
    Processing by BooksController#index as HTML
    @books is assigned in /path_to_app/app/controllers/books_controller.rb:7 index BooksController
    @books is assigned in /path_to_appapp/controllers/books_controller.rb:8 index BooksController
    Rendering books/index.html.erb within layouts/application
    Rendered books/index.html.erb within layouts/application (50.2ms)
    Completed 200 OK in 3146ms (Views: 2867.5ms | ActiveRecord: 0.0ms)
    /books ΁ΞΫηεͨ͠ϩά
    ⬆ ݕ஌!!
    ⬅ books_controller.rb:8
    books_controller.rb:7,8 Ͱͷ୅ೖݕ஌͕Ͱ͖ͨ
    ൜ਓ֬อ!!
    ⬅ books_controller.rb:7

    View Slide

  45. Πϯελϯεม਺୅ೖݕ஌
    ݕ஌Ͱ͖ͳ͍έʔε͕͋Δ
    Started GET "/books" for ::1 at 2019-06-08 12:55:09 +0900
    Processing by BooksController#index as HTML
    @books is assigned in /path_to_app/app/controllers/books_controller.rb:7 index BooksController
    Rendering books/index.html.erb within layouts/application
    Rendered books/index.html.erb within layouts/application (83.2ms)
    Completed 200 OK in 2881ms (Views: 2742.1ms | ActiveRecord: 0.0ms)
    /books ΁ΞΫηεͨ͠ϩά
    ⬇ίϯτϩʔϥͰͷ୅ೖ͸ݕ஌
    ⬅ books_controller.rb:7
    books_controller.rb:7 Ͱʢਖ਼ৗͳʣ୅ೖݕ஌͸Ͱ͖͍ͯΔ
    ൜ਓͷݕ஌͸
    Ͱ͖͍ͯͳ͍

    View Slide

  46. Πϯελϯεม਺୅ೖݕ஌
    ͜ͷํ๏Ͱ͸ViewͰͷ୅ೖΛݕ஌Ͱ͖ͳ͔ͬͨ
    app/view/books/index.html.erb
    <% @books = [] %>
    ...
    <% @books.each do |book| %>
    ⬅ ൜ਓ͕Viewʹ͍Δͱ͖ɺ͜ͷ୅ೖΛݕ஌Ͱ͖ͳ͍
    line #=> "<% @books= [] %>\n"
    erbͳͷͰલޙʹ <% %> ͕෇͍͍ͯΔ
    ※ݟ౰ҧ͍ͯͯ͠ղܾʹ1ϲ݄͔͔ͬͨ
    ݪҼ
    RubyVM::AbstractSyntaxTree.parse(line).children.last
    #=> SyntaxError

    View Slide

  47. Πϯελϯεม਺୅ೖݕ஌
    erbରԠ
    લޙʹ <% %> ͕෇͍͍ͯͨΒ֎͢
    ↖ line = match_data.captures.first
    ↙ line.match(/\A\s*<%=*(.*)%>\s*\z/)
    Ruby௒ೖ໳ P. 271 ਖ਼نදݱ
    ASTऔಘΑΓޙΖ͸ಉ͡
    ਖ਼نදݱதͷ(.*)෦෼औಘ
    https://docs.ruby-lang.org/ja/latest/class/MatchData.html

    View Slide

  48. Πϯελϯεม਺୅ೖݕ஌
    erbରԠ
    Started GET "/books" for ::1 at 2019-06-09 09:55:08 +0900
    (12.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY
    "schema_migrations"."version" ASC
    ↳ /Users/igaiga/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/
    log_subscriber.rb:98
    Processing by BooksController#index as HTML
    @books is assigned in /path_to_app/app/controllers/books_controller.rb:7 index BooksController
    Rendering books/index.html.erb within layouts/application
    @books is assigned in /path_to_app/app/views/books/index.html.erb:1
    _app_views_books_index_html_erb__4042701126060758541_70158372829520
    ActionView::CompiledTemplates
    Rendered books/index.html.erb within layouts/application (76.8ms)
    Completed 200 OK in 13765ms (Views: 13457.4ms | ActiveRecord: 0.0ms)
    ൜ਓ֬อ!!
    ↖index.html.erb:1
    <% @books = [] %>

    View Slide

  49. നຐज़ೖ໳ ʮ౪·ΕͨΠϯελϯεม਺ʯ·ͱΊ
    • Πϯελϯεม਺୅ೖݕ஌खॱͷҰྫ
    • TracePoint :line ͰϑοΫ
    • TracePointͷ৘ใ͔ΒιʔεϑΝΠϧऔಘ
    • RubyVM::AbstractSyntaxTree.parseͰղੳ
    • Πϯελϯεม਺୅ೖ͸IASGN
    • ͜͜Ͱग़͖ͯͨιʔείʔυ
    • https://github.com/igaiga/tmrk01
    • instance_variable_tracer gem ͱͯ͠ެ։
    • https://github.com/igaiga/instance_variable_tracer

    View Slide

  50. നຐज़֓࿦
    ͦͷଞͷനຐज़
    • Tracer
    • ObjectSpace#allocation_sourcefile
    • g
    • signal & trap
    ⏰28

    View Slide

  51. Tracerඪ४ఴ෇ϥΠϒϥϦ
    ϩάग़ྗ https://docs.ruby-lang.org/ja/latest/class/Tracer.html
    தͰ Kernel.#set_trace_func Λར༻
    શ࣮ߦߦϩά(ιʔείʔυೖΓ)ΛϑΝΠϧग़ྗͯ͠grepͰௐ΂Δ
    log.txt
    ...
    #1:/path_to_app/app/views/books/index.html.erb:1:ActionView::CompiledTemplates:-: <%= @books = [] %>
    ...
    Tracer.add_filter do |event, file, line, id, binding, klass|
    file == "/path_to_app/app/views/books/index.html.erb"
    end
    Tracer.on
    ϑΟϧλʔ͢Δ͜ͱ΋Մೳ
    ϑΟϧλʔதͰ͸ιʔείʔυΛ௚઀औΕͳ͍ʢ͸ͣʣ
    = TracePointͱಉ͘͡ඞཁͳΒιʔεϑΝΠϧ͔Βऔಘ

    View Slide

  52. ObjectSpace.allocation_sourcefile
    ΦϒδΣΫτͷੜ࢈஍Λ஌Δ
    ͜͜·Ͱઆ໌͖ͯͨ͠࡞ઓ: Ͳ͜ͰΠϯελϯεม਺΁୅ೖ͞Ε͔ͨΛ஌Δ
    ৽࡞ઓ: Ͳ͜ͰΦϒδΣΫτ͕࡞ΒΕ͔ͨΛ஌Δ
    ObjectSpaceͱobjspaceϥΠϒϥϦ
    ObjectSpace͸૊ΈࠐΈϥΠϒϥϦ
    objspace͸ObjectSpaceʹ௥ՃͰϝιουΛੜ΍͢ඪ४ఴ෇ϥΠϒϥϦ
    ObjectSpace.allocation_sourcefile ΦϒδΣΫτͷੜ੒ݩϑΝΠϧ
    ObjectSpace.allocation_sourceline ΦϒδΣΫτͷੜ੒ݩϑΝΠϧߦ൪߸
    #=> {"path_to_app/app/views/books/index.html.erb"=>1}

    View Slide

  53. g gem
    ೿खͳσόοά https://github.com/jugyo/g
    p ϝιουͷnotification൛

    View Slide

  54. station_signage gem with g
    https://github.com/igaiga/station_signage

    View Slide

  55. station_signage gem with g
    https://github.com/igaiga/station_signage
    application_controller.rb
    before_action { g "#{self.class.name}##{action_name}" }
    gem "g"
    gem "terminal-notifier"
    ⬆g gem͕಺෦Ͱར༻͢Δgem
    ΍ͬͯΔ͜ͱ
    ϦΫΤετͨ͠ϖʔδͷίϯτϩʔϥ໊ɺΞΫγϣϯ໊Λදࣔ

    View Slide

  56. signal & trap
    ࣌ؒ࣠Ͱσόοά
    ⬅ infoγάφϧΛड͚औΔͱಈ͘
    macͰ͸ ctrl-T Ͱ infoγάφϧΛൃੜ
    ·ͨ͸ $ kill -s info [pid]
    http://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html

    View Slide

  57. Τϐϩʔά
    ⏰32

    View Slide

  58. നຐज़͸ΦϒδΣΫτͨͪͷ෣୆Λ؍Δຐ๏
    നຐज़Λ࢖͏ͱ
    ෣୆্ͷΦϒδΣΫτͨͪͱର࿩ͨ͠Γ
    ༷ࢠΛ஌Δ͜ͱ͕Ͱ͖Δ
    ΦϒδΣΫτͷੈք ➡
    ιʔείʔυͷੈք ➡ Integer String Hash

    View Slide

  59. നຐज़͸ਓΛ༊΍͢ຐ๏
    ϓϩάϥϛϯάͷଟ͘ͷ࣌ؒ͸
    σόοάʹඅ΍͞ΕΔ
    σόοάΛָʹͰ͖ΔΑ͏ʹͳΕ͹ɺ
    ͦΕ͸ࢲͨͪ΁༊΍͠ͱͳΔ
    ΋ͬͱྑ͍σόοάͷٕज़͸͋Δ͸ͣͩ͠ɺ
    ΋ͬͱମܥͩͬͨσόοάຊ͕͋ͬͯ΋ྑ͍
    দా͞Μͷstill_lifeͱ͔hocus_pocusͱ͔ΊͬͪΌศརͰ͔͍͍ͬ͜

    View Slide

  60. നຐज़ͱࠇຐज़͸දཪҰମ
    ࠇຐज़Λֶ΂͹നຐज़ͷεΩϧ΋ಘΔ
    നຐज़Λֶ΂͹ࠇຐज़ͷεΩϧ΋ಘΔ
    നຐज़͸ࠇຐज़ͱͯ͠࢖͏͜ͱ΋Ͱ͖Δ
    ڧྗͳྗΛͲ͏࢖͏͔͸͋ͳͨ࣍ୈ

    View Slide

  61. ϝλϓϩάϥϛϯάRuby matzংจ
    ʮRuby͸܅Λ৴པ͢ΔɻRuby͸܅Λ෼ผ
    ͷ͋ΔϓϩάϥϚͱͯ͠ѻ͏ɻRuby͸ϝλ
    ϓϩάϥϛϯάͷΑ͏ͳڧྗͳྗΛ༩͑
    Δɻͨͩ͠ɺେ͍ͳΔྗʹ͸େ͍ͳΔ੹೚
    ͕൐͏͜ͱΛ๨Εͯ͸͍͚ͳ͍ɻʯ

    View Slide

  62. ʮͦΕͰ͸ɺ
    RubyͰ
    ͨͷ͍͠ϓϩάϥϛϯάΛɻʯ
    matz

    View Slide

  63. View Slide

  64. Χʔςϯίʔϧ

    View Slide

  65. ࢀߟࢿྉ
    • Hijacking Ruby Syntax in Ruby
    • https://www.youtube.com/watch?v=04HGQEw3A6Y
    • RubyVM::AbstractSyntaxTree::Node ৄࡉ
    • https://qiita.com/siman/items/3017ed399ded43229189
    • I am a puts debugger
    • http://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html
    • Ruby Debugging Magic Cheat Sheet
    • https://www.schneems.com/2016/01/25/ruby-debugging-magic-cheat-sheet.html
    • rubyͰ͍͍͔Μ͡ʹDI͢Δhabuͷ঺հ
    • https://qiita.com/hanachin_/items/8aa4bd82258bb19b7f91
    • †Rubyࠇຐज़ܦయ†
    • https://speakerdeck.com/joker1007/rubyhei-mo-shu-jing-dian
    • Railsdm Podcast unasuke.fm #5 Ruby Tendency
    • https://soundcloud.com/railsdm

    View Slide

  66. ँࣙ (ܟশུ)
    Ғେͳࠇຐज़ࢣͷΈͳ͞Μ
    joker, moris, koic, hanachin, siman, alitaso
    ૬ஊʹ৐ͬͯͩͬͨ͘͞Έͳ͞Μ
    ko1, mame, _tad_
    ωλΛఏڙͯ͘͠ΕͨΈͳ͞Μ
    aaron, jugyo
    Ruby௒ೖ໳νʔϜͷΈͳ͞Μ
    machu, beco
    ࢲ͕RubyΛ࢝ΊΔ͖͔͚ͬʹͳͬͨtDiary։ൃνʔϜͷΈͳ͞Μ
    tdtds, hsbt, machu
    ࠓ೔ͷ४උΛͯ͘͠ΕͨελοϑͷΈͳ͞Μ

    View Slide

  67. ੒Ռ
    • bugs.ruby-lang ىථ "Tracing instance variable assignment"
    • https://bugs.ruby-lang.org/issues/15854
    • instance_variable_tracer gem ࡞੒
    • https://github.com/igaiga/station_signage
    • station_signage gem ࡞੒
    • https://github.com/igaiga/station_signage
    • RubyConf୆࿷ CFP ࠾୒
    • Rubyͷ஌ࣝ

    View Slide

  68. ޒेཛྷ๜໌/igaiga ࣗݾ঺հ
    ৽͍͠࢓ࣄ͸ืू͍ͯ͠·ͤΜ͕ɺࡳଋͷ͝༻ҙ͕͋Δํ͸͓੠͔͚͍ͩ͘͞
    ϑϦʔϥϯεRails/RubyΤϯδχΞ
    औҾઌ: NaCl͞Μ, ϐΫγϒ͞Μ, OSCR͞Μ, IDCϑϩϯςΟΞ͞Μ,
    Classi͞Μ, αΠόʔηΩϡϦςΟΫϥ΢υ͞Μ, GMOϖύϘ͞Μ
    ஶॻ: ʮθϩ͔ΒΘ͔ΔRuby௒ೖ໳ʯʮRailsͷڭՊॻʯ
    ʮRubyͱRailsͷֶशΨΠυʯ
    https://twitter.com/igaiga555

    View Slide

  69. View Slide

  70. ΨʔωοτςοΫ373גࣜձࣾ
    2019.7.1 ઃཱ

    View Slide

  71. View Slide