Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

ࣗݾ঺հ • ϑϦʔϥϯεRails/RubyΤϯδχΞ • ஶॻ • Ruby௒ೖ໳ • RailsͷڭՊॻ • RubyͱRailsͷֶशΨΠυ

Slide 3

Slide 3 text

ࠓճͷํ਑ • ґཔʮجௐߨԋͰ͕͢ςΫ͍࿩Ͱ͓ئ͍͠·͢ʯ • ຊձٞͷςʔϚ͸ʮ੒௕ʯ • ڵຯ͋Δ͜ͱΛௐ΂ͯൃද͍ͨ͠ͱࢥͬͨ • ࢲ΋3ϲ݄લʹ͸஌Βͳ͔ͬͨ͜ͱ͹͔Γ࿩͠·͢ • Ruby௒ೖ໳ͳͲஶॻͷ࿩͸͋·Γ͠·ͤΜ • ସΘΓʹॻ੶Ͱઆ໌ͨ͠಺༰ʹ ϚʔΫ෇͚·ͨ͠

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

ϓϩϩʔά

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

σόοΨͷ࢖͍ํ ϓϩάϥϜΛ࣮ߦ్தͰҰ࣌ఀࢭͯ͠ϓϩάϥϜΛ࣮ߦ͢Δ • 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͢Δͱָ

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

͋ͳͨ͸Ͳ͔͜Βདྷ·͔ͨ͠ʁ ιʔείʔυฤ • 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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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ΦϒδΣΫτ

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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ΦϒδΣΫτ͕ੵ૚

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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 ୅ೖίʔυ

Slide 43

Slide 43 text

Πϯελϯεม਺୅ೖݕ஌ 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 ୅ೖݕ஌ίʔυ

Slide 44

Slide 44 text

Πϯελϯεม਺୅ೖݕ஌ ίϯτϩʔϥʹ൜ਓ͕͍ͨέʔε 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

Slide 45

Slide 45 text

Πϯελϯεม਺୅ೖݕ஌ ݕ஌Ͱ͖ͳ͍έʔε͕͋Δ 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 Ͱʢਖ਼ৗͳʣ୅ೖݕ஌͸Ͱ͖͍ͯΔ ൜ਓͷݕ஌͸ Ͱ͖͍ͯͳ͍

Slide 46

Slide 46 text

Πϯελϯεม਺୅ೖݕ஌ ͜ͷํ๏Ͱ͸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

Slide 47

Slide 47 text

Πϯελϯεม਺୅ೖݕ஌ 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

Slide 48

Slide 48 text

Πϯελϯεม਺୅ೖݕ஌ 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 = [] %>

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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ͱಉ͘͡ඞཁͳΒιʔεϑΝΠϧ͔Βऔಘ

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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 ΍ͬͯΔ͜ͱ ϦΫΤετͨ͠ϖʔδͷίϯτϩʔϥ໊ɺΞΫγϣϯ໊Λදࣔ

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

Τϐϩʔά ⏰32

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

Χʔςϯίʔϧ

Slide 65

Slide 65 text

ࢀߟࢿྉ • 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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

੒Ռ • 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ͷ஌ࣝ

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

No content