Slide 1

Slide 1 text

೗Կ࢖༻ byebug ိআ ࡨ Ruby ఔࣜ John Lin

Slide 2

Slide 2 text

᮫ԙզ • John Lin • Twitter: @johnlinvc • Senior Solution Architect, DevOps 
 @ West Pharmaceutical Service (୆ᖯҖ๏෰຿)

Slide 3

Slide 3 text

Լࡌ໢ᅿ • ౤Өย࿨ఔࣜᛰ౎์ࡏ https://git.io/JJVqt • େ֓ੋṜݸ talk ࠷༗༻తҰ ทɻ

Slide 4

Slide 4 text

ৗݟత debug ໰୊ • ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ • ෆ֬ఆᏓᏐతᆴੋଟগɻ • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ

Slide 5

Slide 5 text

ৗݟత debug ํ๏ • ؃/፺ਘ code => ࢖༻ਓᡵฤᩄث/௚ᩄثɻ • ࢖༻ puts େ๏ɻ • ࢖༻আࡨثɻ

Slide 6

Slide 6 text

ྖંၢ݊ coupon.rb def get_coupon(user_id, history) if history[user_id] = true return 0 end history[user_id] = true 3000 end puts get_coupon(1, {}) Ṝछศᑍࢴཫ౎ੋఔࣜᛰ

Slide 7

Slide 7 text

ྖંၢ݊ coupon.rb $ ruby coupon.rb 0 def get_coupon(user_id, history) if history[user_id] = true return 0 end history[user_id] = true 3000 end puts get_coupon(1, {}) Ṝछศᑍࢴཫ౎ੋఔࣜᛰ →৭ᐽཫੋbash/byebug ࿨༬ظෆಉɼጯ֘ཁ༌ग़ 3000

Slide 8

Slide 8 text

༻ puts ֬ೝఔࣜ။ෆ။ඃࣥߦ౸ def get_coupon(user_id, history) if history[user_id] = true return 0 end puts "here" history[user_id] = true 3000 end puts get_coupon(1, {}) ೗Ռ༗ࣥߦ౸Ṝཫब။༌ग़ here

Slide 9

Slide 9 text

༻ puts ֬ೝఔࣜ။ෆ။ඃࣥߦ౸ $ ruby coupon_here.rb 0 def get_coupon(user_id, history) if history[user_id] = true return 0 end puts "here" history[user_id] = true 3000 end puts get_coupon(1, {}) ೗Ռ༗ࣥߦ౸Ṝཫब။༌ग़ here ᔒ༗ hereɼ
 ॴҎᔒ༗ࣥߦ౸ਖ਼֬తҐஔ

Slide 10

Slide 10 text

byebug • ໋ྩྻత Ruby আࡨثɻ • ࢖༻ TracePoint API ိሣ Ruby ఔࣜআࡨɻ • ࢧԉ MRI Ruby 2.4.0 Ҏ্ɻ ෆࢧԉ jruby, rubinius ౳ଖଞ Ruby ௚ᩄثɻ

Slide 11

Slide 11 text

ॄኄੋআࡨث • Ұछ༻ԙআࡨଖሏఔࣜతిᡵఔࣜٴ޻۩ɻ(from wiki) • ఏڙதᏗᴍɼᄸ㑊ࣥߦɼᒾࢹᏓᏐ ౳ޭೳɻ

Slide 12

Slide 12 text

҆᧋ • ࢖༻ bundler ိ҆᧋ • ࡏ Gemfile ཫՃೖ 
 gem 'byebug' • ࣥߦ bundle install

Slide 13

Slide 13 text

࢖༻ byebug root@coscup:/app# byebug coupon.rb [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug)

Slide 14

Slide 14 text

ᙘ໘ղ㘸 root@coscup:/app# byebug coupon.rb [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) 䈕໊᪑ߦᏐൣᅴ

Slide 15

Slide 15 text

ᙘ໘ղ㘸 root@coscup:/app# byebug coupon.rb [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) ఔࣜᛰ࿨ߦᥒ

Slide 16

Slide 16 text

ᙘ໘ղ㘸 root@coscup:/app# byebug coupon.rb [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) ඪࣔ໨લ
 ఀࢭҐஔ

Slide 17

Slide 17 text

ᙘ໘ղ㘸 root@coscup:/app# byebug coupon.rb [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) prompt ɼඪࣔ䬟زߦੋզ၇༌ೖతࢦྩ

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

཭։ byebug [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) quit Really quit? (y/n) y root@coscup:/app#

Slide 20

Slide 20 text

help • byebug ༗㚎ݐ㘸໌ࢦྩɻ • ࡏ prompt ༌ೖ help बՄҎ؃౸ࢦྩྻදɻ (byebug) help

Slide 21

Slide 21 text

help (byebug) help break -- Sets breakpoints in the source code catch -- Handles exception catchpoints condition -- Sets conditions on breakpoints continue -- Runs until program ends, hits a breakpoint or reaches a line debug -- Spawns a subdebugger delete -- Deletes breakpoints disable -- Disables breakpoints or displays display -- Evaluates expressions every time the debugger stops down -- Moves to a lower frame in the stack trace edit -- Edits source files enable -- Enables breakpoints or displays finish -- Runs the program until frame returns frame -- Moves to a frame in the call stack help -- Helps you using byebug history -- Shows byebug's history of commands info -- Shows several informations about the program being debugged interrupt -- Interrupts the program irb -- Starts an IRB session kill -- Sends a signal to the current process list -- Lists lines of source code method -- Shows methods of an object, class or module next -- Runs one or more lines of code pry -- Starts a Pry session quit -- Exits byebug restart -- Restarts the debugged program save -- Saves current byebug session to a file set -- Modifies byebug settings show -- Shows byebug settings skip -- Runs until the next breakpoint as long as it is different from the current one source -- Restores a previously saved byebug session step -- Steps into blocks or methods one or more times thread -- Commands to manipulate threads

Slide 22

Slide 22 text

help • byebug ༗㚎ݐ㘸໌ࢦྩɻ • ࡏ prompt ༌ೖ help बՄҎ؃౸ࢦྩྻදɻ • ࡏ prompt ༌ೖ help <ࢦྩ> बՄҎ؃౸ࢦྩత㘸໌ɻ (byebug) help (byebug) help help

Slide 23

Slide 23 text

h[elp] (byebug) help help h[elp][ [ ]] Helps you using byebug help -- prints a summary of all commands help -- prints help on command help -- prints help on 's subcommand [ ] 㚎త෦෼ੋબᎩੑతɼॴҎ໵ՄҎ୞ଧ h

Slide 24

Slide 24 text

l[ist] • ؃ݱࡏࣥߦ౸䬟Ұߦࢦྩɻ။༌ग़ෟۙతزߦɻ (byebug) list [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {})

Slide 25

Slide 25 text

b[reak] • ཁٻ byebug ࡏࣥߦ౸ࢦఆߦᏐલఀԼိɻఀԼိతҐஔɼ ላ໊ڣ၏ ”தᏗᴍ“
 • ໵ՄҎ༻؆ሜ b
 (byebug) break 2 Created breakpoint 1 at /app/coupon.rb:2 (byebug) b 3 Created breakpoint 3 at /app/coupon.rb:3

Slide 26

Slide 26 text

continue • c[ontinue] ࢦྩ။ᩋ࢑ఀతఔࣜ៺᠃ࣥߦɼ௚౸۰౸ԼҰݸ தᏗᴍҝࢭɻ (byebug) continue

Slide 27

Slide 27 text

༻ byebug ֬ೝఔࣜ။ෆ။ඃࣥߦ౸ [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) break 5 Created breakpoint 1 at /app/coupon.rb:5 (byebug) ૝֬ఆ။ࣥߦୈ 5 ߦ

Slide 28

Slide 28 text

༻ byebug ֬ೝఔࣜ။ෆ။ඃࣥߦ౸ [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) break 5 Created breakpoint 1 at /app/coupon.rb:5 (byebug) ཁٻࡏࣥߦୈ 5 ߦ࣌ఀԼိ

Slide 29

Slide 29 text

༻ byebug ֬ೝఔࣜ။ෆ။ඃࣥߦ౸ [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) break 5 Created breakpoint 1 at /app/coupon.rb:5 (byebug) continue ཁٻ៺᠃ࣥߦ

Slide 30

Slide 30 text

༻ byebug ֬ೝఔࣜ။ෆ။ඃࣥߦ౸ [1, 9] in /app/coupon.rb => 1: def get_coupon(user_id, history) 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) break 5 Created breakpoint 1 at /app/coupon.rb:5 (byebug) continue 0 root@coscup:/app# ᔒ༗ఀԼိब݁ଋྃɼॴҎୈ 5 ߦੋᔒ༗ࣥߦ౸తɻ

Slide 31

Slide 31 text

n[ext] • ࣥߦݱࡏṜߦఔࣜɻฒ׌ࡏԼҰߦఀԼိɻ • ՄҎ؃౸ԼҰߦ။ࣥߦਙኄɻ • ༻puts େ๏త࿩ཁࡏ㑌Ұݸ෼ࢧᴍ౎ putsɻ

Slide 32

Slide 32 text

[1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) => 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) next [1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) 2: if history[user_id] = true => 3: return 0 4: end ݱࡏࣥߦ౸ୈ 2 ߦ

Slide 33

Slide 33 text

[1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) => 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) next [1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) 2: if history[user_id] = true => 3: return 0 4: end ࣥߦԼҰߦ

Slide 34

Slide 34 text

[1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) => 2: if history[user_id] = true 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) next [1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) 2: if history[user_id] = true => 3: return 0 4: end ݱࡏࣥߦ౸ྃୈࡾߦ

Slide 35

Slide 35 text

ෆੋ㑌ݸ஍ํ౎ೳதᏗ • ༗Ұࠣᔒ༗ࣥߦҙٛత஍ํੋෆೳதᏗతɻ૾ੋۭߦɼ end, {, }ɻ (byebug) break /app/coupon.rb:4 *** Line 4 is not a valid breakpoint in file /app/coupon.rb. Valid break points are: [B] 1: def get_coupon(user_id, history) [B] 2: if history[user_id] = true [B] 3: return 0 4: end ᔒ༗ඪ [B] తߦᏐແ๏தᏗ

Slide 36

Slide 36 text

ࡏಛఆ৘گԼ break • ՄҎ୞༗ࡏಛఆత৘گԼ break • break [file:]line [if ]
 (byebug) break 3 if history[user_id] Created breakpoint 5 at /app/coupon.rb:3

Slide 37

Slide 37 text

ࡏ rails server ༻ byebug • rails 4.2 ೭ޙब༬ઃࡏ։ᚙ໛ࣜ҆᧋ byebug • ࡏ code ཫ࢖༻ byebug method ိࡏࣥߦఔࣜత࣌ީఀࡏ byebug ႔ɻ • ඇ rails తఔࣜ require 'byebug' ޙ໵Մ༻ byebug methodɻ • ෆա byebug method ෆࢉੋதᏗᴍɻ

Slide 38

Slide 38 text

ࡏ rails ཫ࢖༻ byebug Started GET "/posts" for 127.0.0.1 at 2020-08-01 12:18:37 +0000 Processing by PostsController#index as */* [3, 12] in /app/rails_example/app/controllers/ posts_controller.rb 3: 4: # GET /posts 5: # GET /posts.json 6: def index 7: byebug => 8: @posts = Post.all 9: end 10: 11: # GET /posts/1 12: # GET /posts/1.json (byebug) ။ఀࡏ byebug తԼҰߦ

Slide 39

Slide 39 text

ࡏඇ rails ཫ࢖༻ byebug $ ruby coupon_byebug.rb [1, 10] in /app/coupon_byebug.rb 1: require 'byebug' 2: def get_coupon(user_id, history) 3: byebug => 4: if history[user_id] = true 5: return 0 6: end 7: history[user_id] = true 8: 3000 9: end 10: (byebug) ઌ require ࠽ೳ࢖༻ byebug

Slide 40

Slide 40 text

ᑍ݅ࣜ byebug • code ཫత byebug बੋҰൠత ruby methodɻՄҎ์ࡏ೚ Կ஍ํɼ໵ՄҎ༻ if ိઃఆᑍ݅ ɻ
 $ ruby coupon_byebug_cond.rb [1, 10] in /app/coupon_byebug_cond.rb 1: require 'byebug' 2: def get_coupon(user_id, history) 3: byebug if user_id == 1 => 4: if history[user_id] = true 5: return 0 ୞༗ᑍ݅ූ߹࣌࠽தᏗ

Slide 41

Slide 41 text

• ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ • ෆ֬ఆᏓᏐతᆴੋଟগɻ • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ ৗݟత debug ໰୊

Slide 42

Slide 42 text

༻ puts ֬ೝᏓᏐతᆴ def get_coupon(user_id, history) if history[user_id] = true puts user_id puts history return 0 end history[user_id] = true 3000 end puts get_coupon(1, {}) $ ruby coupon_puts_val.rb 1 {1=>true} 0

Slide 43

Slide 43 text

༻ byebug ֬ೝᏓᏐతᆴ [1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) 2: if history[user_id] = true => 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) user_id 1

Slide 44

Slide 44 text

[1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) 2: if history[user_id] = true => 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) history 1 help 2 help help 3 list

Slide 45

Slide 45 text

[1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) 2: if history[user_id] = true => 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) history 1 help 2 help help 3 list

Slide 46

Slide 46 text

ᙛ࿨㚎ݐࢦྩিಥ࣌ɼ ࢖༻ eval [1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) 2: if history[user_id] = true => 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) eval('history') {1=>true}

Slide 47

Slide 47 text

v[ar] • v[ar] args ɿྻग़ method తჩᏐɻ • v[ar] c[onst] ɿྻग़ݱࡏ scope 㚎త constantɻ • v[ar] i[nstance] [object] ɿྻग़ object ҃ੋ self త ivarɻ • v[ar] l[ocal]ɿྻग़ॴ༗ local ᏓᏐɻ • v[ar] a[ll]ɿྻग़ local, global, instance ᏓᏐɻ

Slide 48

Slide 48 text

[1, 9] in /app/coupon.rb 1: def get_coupon(user_id, history) 2: if history[user_id] = true => 3: return 0 4: end 5: history[user_id] = true 6: 3000 7: end 8: 9: puts get_coupon(1, {}) (byebug) var local history = {1=>true} user_id = 1

Slide 49

Slide 49 text

ෆ୞᧺࡯ɼؐՄҎհೖ [1, 2] in /app/modify_var.rb => 1: a = 1 2: puts "a is: #{a}" (byebug) n [1, 2] in /app/modify_var.rb 1: a = 1 => 2: puts "a is: #{a}" (byebug) a = 56 56 (byebug) c a is: 56 a = 1 puts "a is: #{a}"

Slide 50

Slide 50 text

• ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ • ෆ֬ఆᏓᏐతᆴੋଟগɻ • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ ৗݟత debug ໰୊

Slide 51

Slide 51 text

༻ puts ፙᏓᏐඃमվతҐஔ def get_coupon(user_id, history) puts history if history[user_id] = true puts history return 0 end history[user_id] = true 3000 end puts get_coupon(1, {}) $ ruby coupon_puts_find.rb {} {1=>true} 0

Slide 52

Slide 52 text

༻ byebug ፙᏓᏐඃमվతҐஔ (byebug) display history 1: history = (undefined) (byebug) set linetrace linetrace is on (byebug) continue Tracing: /app/coupon.rb:9 puts get_coupon(1, {}) 1: history = (undefined) Tracing: /app/coupon.rb:2 if history[user_id] = true 1: history = {} Tracing: /app/coupon.rb:3 return 0 1: history = {1=>true}

Slide 53

Slide 53 text

display expr • ࡏ఍ୡ㑌ݸதᏗᴍత࣌ީɼ။ࣗಈࣥߦ exprɻ • expr ՄҎ༗෭࡞༻ɻdisplay x+=1 ။վᏓఔࣜཫ x తᆴɻ

Slide 54

Slide 54 text

༻ byebug ፙᏓᏐඃमվతҐஔ (byebug) display history 1: history = (undefined) (byebug) set linetrace linetrace is on (byebug) continue Tracing: /app/coupon.rb:9 puts get_coupon(1, {}) 1: history = (undefined) Tracing: /app/coupon.rb:2 if history[user_id] = true 1: history = {} Tracing: /app/coupon.rb:3 return 0 1: history = {1=>true}

Slide 55

Slide 55 text

set linetrace • ࣗಈࡏ㑌Ұߦఔࣜ࢑ఀ೭ޙཱࠁࣥߦɻ౥഑ display expr बՄҎࡏ㑌Ұߦఔࣜ౎ࣥߦ expr ိ؂߇ఔࣜࣥߦաఔɻ • set nolinetrace ՄҎ᮫ᎃɻ

Slide 56

Slide 56 text

༻ byebug ፙᏓᏐඃमվతҐஔ (byebug) display history 1: history = (undefined) (byebug) set linetrace linetrace is on (byebug) continue Tracing: /app/coupon.rb:9 puts get_coupon(1, {}) 1: history = (undefined) Tracing: /app/coupon.rb:2 if history[user_id] = true 1: history = {} Tracing: /app/coupon.rb:3 return 0 1: history = {1=>true}

Slide 57

Slide 57 text

༻ byebug ፙᏓᏐඃमվతҐஔ (byebug) display history 1: history = (undefined) (byebug) set linetrace linetrace is on (byebug) continue Tracing: /app/coupon.rb:9 puts get_coupon(1, {}) 1: history = (undefined) Tracing: /app/coupon.rb:2 if history[user_id] = true 1: history = {} Tracing: /app/coupon.rb:3 return 0 1: history = {1=>true}

Slide 58

Slide 58 text

༻ byebug ፙᏓᏐඃमվతҐஔ (byebug) display history 1: history = (undefined) (byebug) set linetrace linetrace is on (byebug) continue Tracing: /app/coupon.rb:9 puts get_coupon(1, {}) 1: history = (undefined) Tracing: /app/coupon.rb:2 if history[user_id] = true 1: history = {} Tracing: /app/coupon.rb:3 return 0 1: history = {1=>true}

Slide 59

Slide 59 text

• ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ • ෆ֬ఆᏓᏐతᆴੋଟগɻ • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ ৗݟత debug ໰୊

Slide 60

Slide 60 text

౸ఈݺڣྃ䬟Ұஈఔࣜ? require_relative 'hidden_lib.rb' puts HiddenLib.new.hello("world") $ grep 'hello' hidden_lib.rb $ ፙෆ౸ hello Ṝݸࣈ۲ʁʁ $ ruby method_caller.rb called hello with args: ["world"]

Slide 61

Slide 61 text

౸ఈݺڣྃ䬟Ұஈఔࣜ? # method_caller.rb require_relative 'hidden_lib.rb' puts HiddenLib.new.hello("world") $ grep 'hello' hidden_lib.rb $ ፙෆ౸ hello Ṝݸࣈ۲ʁʁ $ ruby method_caller.rb called hello with args: ["world"]

Slide 62

Slide 62 text

class HiddenLib # hidden_lib.rb def method_missing(name, *args) "called #{name} with args: #{args.map(&:to_s)}" end end ౸ఈݺڣྃ䬟Ұஈఔࣜ? # method_caller.rb require_relative 'hidden_lib.rb' puts HiddenLib.new.hello("world") ׬શᔒ༗ hello Ṝݸࣈ۲ʂʂ $ ruby method_caller.rb called hello with args: ["world"]

Slide 63

Slide 63 text

"ஶ໊"త method_missing • method_missing ੋᙛ object ඃݺڣෆଘࡏత method ɼब ။վҝݺڣṜݸ methodɻඃݺڣత method ໊᜝࿨ሏతჩ Ꮠ౎။ੋ method_missing తჩᏐɻ Ruby on Rails ࢖༻ྃ ෆগత method_missingɻ • obj.foo(a,b) => obj.method_missing(:foo, [a,b])

Slide 64

Slide 64 text

class HiddenLib # hidden_lib.rb def method_missing(name, *args) "called #{name} with args: #{args.map(&:to_s)}" end end ༻ puts ፙඃݺڣతఔࣜ # method_caller.rb require_relative 'hidden_lib.rb' puts HiddenLib.new.hello("world")

Slide 65

Slide 65 text

༻ byebug ፙඃݺڣతఔࣜ [1, 3] in /app/method_caller.rb 1: require_relative 'hidden_lib.rb' 2: => 3: puts HiddenLib.new.hello("world") (byebug) step [1, 5] in /app/hidden_lib.rb 1: class HiddenLib 2: def method_missing(name, *args) => 3: "called #{name} with args: #{args.map(&:to_s)}" 4: end 5: end (byebug)

Slide 66

Slide 66 text

s[tep] [1, 3] in /app/method_caller.rb 1: require_relative 'hidden_lib.rb' 2: => 3: puts HiddenLib.new.hello("world") (byebug) step [1, 5] in /app/hidden_lib.rb 1: class HiddenLib 2: def method_missing(name, *args) => 3: "called #{name} with args: #{args.map(&:to_s)}" 4: end 5: end (byebug) • ᄸ㑊ࣥߦਐೖඃݺڣత methodɻ

Slide 67

Slide 67 text

• ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ • ෆ֬ఆᏓᏐతᆴੋଟগɻ • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ ৗݟత debug ໰୊

Slide 68

Slide 68 text

framework vs library Framework త code զ၇త code զ၇త code Library త code

Slide 69

Slide 69 text

୭ݺڣྃṜҰஈఔࣜ? $ ./framework hello # my_code.rb def my_method "hello" end

Slide 70

Slide 70 text

༻ puts ፙݺڣ႔ $ ./framework (eval):1:in `' ./framework:4:in `eval' ./framework:4:in `' hello # my_code.rb def my_method puts caller_locations "hello" end

Slide 71

Slide 71 text

༻ byebug ፙݺڣ႔ ./framework [1, 5] in /app/my_code.rb 1: require 'byebug' 2: def my_method 3: byebug => 4: "hello" 5: end (byebug) where

Slide 72

Slide 72 text

༻ byebug ፙݺڣ႔ ./framework [1, 5] in /app/my_code.rb 1: require 'byebug' 2: def my_method 3: byebug => 4: "hello" 5: end (byebug) where

Slide 73

Slide 73 text

༻ byebug ፙݺڣ႔ ./framework [1, 5] in /app/my_code.rb 1: require 'byebug' 2: def my_method 3: byebug => 4: "hello" 5: end (byebug) where

Slide 74

Slide 74 text

w[here] • ᰖࣔ໨લత call stack ɼ0 ੋ໨લඃݺڣత methodɻᏐࣈ େతݺڣᏐࣈখతɻ ex: 1 ݺڣ 0ɻ (byebug) where --> #0 Object.my_method at /app/my_code.rb:4 #1 at /app/(eval):1 ͱ-- #2 Kernel.eval at /app/framework:4 #3 at /app/framework:4

Slide 75

Slide 75 text

• ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ • ෆ֬ఆᏓᏐతᆴੋଟগɻ • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ ৗݟత debug ໰୊

Slide 76

Slide 76 text

bye ࢦྩখঞ • h[elp] [cmd] • q[uit] • l[ist] • b[reak] [file:]line [if expr] • c[ontinue] • n[ext] • v[ar] l[ocal] • s[tep] • disp[lay] expr • set linetrace • w[here]

Slide 77

Slide 77 text

݁࿦ • byebug ՄҎ㢨ॿզ၇ߋշߋํศ஍ፙग़ఔࣜత໰୊ɻ • ՄҎ࢖༻ byebug ိڠॿզ၇ཧղఔࣜӡ࡞ɻಛผੋᯩଶ෼ ੳᔒ㭎๏႔ཧత෦㟨ɻ

Slide 78

Slide 78 text

Q&A ౤Өย࿨ఔࣜᛰ: https://git.io/JJVqt John Lin Twitter: @johnlinvc