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

如何使用 byebug 來除錯 Ruby 程式

Johnlin
August 02, 2020

如何使用 byebug 來除錯 Ruby 程式

Johnlin

August 02, 2020
Tweet

More Decks by Johnlin

Other Decks in Programming

Transcript

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

    View full-size slide

  2. ᮫ԙզ
    • John Lin

    • Twitter: @johnlinvc

    • Senior Solution Architect, DevOps 

    @ West Pharmaceutical Service (୆ᖯҖ๏෰຿)

    View full-size slide

  3. Լࡌ໢ᅿ
    • ౤Өย࿨ఔࣜᛰ౎์ࡏ
    https://git.io/JJVqt

    • େ֓ੋṜݸ talk ࠷༗༻తҰ
    ทɻ

    View full-size slide

  4. ৗݟత debug ໰୊
    • ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ

    • ෆ֬ఆᏓᏐతᆴੋଟগɻ

    • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ

    • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ

    • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ

    View full-size slide

  5. ৗݟత debug ํ๏
    • ؃/፺ਘ code => ࢖༻ਓᡵฤᩄث/௚ᩄثɻ

    • ࢖༻ puts େ๏ɻ

    • ࢖༻আࡨثɻ

    View full-size slide

  6. ྖંၢ݊ 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, {})
    Ṝछศᑍࢴཫ౎ੋఔࣜᛰ

    View full-size slide

  7. ྖંၢ݊ 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

    View full-size slide

  8. ༻ 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

    View full-size slide

  9. ༻ 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ɼ

    ॴҎᔒ༗ࣥߦ౸ਖ਼֬తҐஔ

    View full-size slide

  10. byebug
    • ໋ྩྻత Ruby আࡨثɻ

    • ࢖༻ TracePoint API ိሣ Ruby ఔࣜআࡨɻ

    • ࢧԉ MRI Ruby 2.4.0 Ҏ্ɻ ෆࢧԉ jruby, rubinius ౳ଖଞ
    Ruby ௚ᩄثɻ

    View full-size slide

  11. ॄኄੋআࡨث
    • Ұछ༻ԙআࡨଖሏఔࣜతిᡵఔࣜٴ޻۩ɻ(from wiki)

    • ఏڙதᏗᴍɼᄸ㑊ࣥߦɼᒾࢹᏓᏐ ౳ޭೳɻ

    View full-size slide

  12. ҆᧋
    • ࢖༻ bundler ိ҆᧋

    • ࡏ Gemfile ཫՃೖ 

    gem 'byebug'

    • ࣥߦ bundle install

    View full-size slide

  13. ࢖༻ 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)

    View full-size slide

  14. ᙘ໘ղ㘸
    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)
    䈕໊᪑ߦᏐൣᅴ

    View full-size slide

  15. ᙘ໘ղ㘸
    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)
    ఔࣜᛰ࿨ߦᥒ

    View full-size slide

  16. ᙘ໘ղ㘸
    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)
    ඪࣔ໨લ

    ఀࢭҐஔ

    View full-size slide

  17. ᙘ໘ղ㘸
    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 ɼඪࣔ䬟زߦੋզ၇༌ೖతࢦྩ

    View full-size slide

  18. ཭։ 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#

    View full-size slide

  19. help
    • byebug ༗㚎ݐ㘸໌ࢦྩɻ

    • ࡏ prompt ༌ೖ help बՄҎ؃౸ࢦྩྻදɻ

    (byebug) help

    View full-size slide

  20. 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

    View full-size slide

  21. help
    • byebug ༗㚎ݐ㘸໌ࢦྩɻ

    • ࡏ prompt ༌ೖ help बՄҎ؃౸ࢦྩྻදɻ

    • ࡏ prompt ༌ೖ help <ࢦྩ> बՄҎ؃౸ࢦྩత㘸໌ɻ

    (byebug) help
    (byebug) help help

    View full-size slide

  22. 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

    View full-size slide

  23. 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, {})

    View full-size slide

  24. 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

    View full-size slide

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

    View full-size slide

  26. ༻ 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 ߦ

    View full-size slide

  27. ༻ 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 ߦ࣌ఀԼိ

    View full-size slide

  28. ༻ 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 ཁٻ៺᠃ࣥߦ

    View full-size slide

  29. ༻ 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 ߦੋᔒ༗ࣥߦ౸తɻ

    View full-size slide

  30. n[ext]
    • ࣥߦݱࡏṜߦఔࣜɻฒ׌ࡏԼҰߦఀԼိɻ

    • ՄҎ؃౸ԼҰߦ။ࣥߦਙኄɻ

    • ༻puts େ๏త࿩ཁࡏ㑌Ұݸ෼ࢧᴍ౎ putsɻ

    View full-size slide

  31. [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 ߦ

    View full-size slide

  32. [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
    ࣥߦԼҰߦ

    View full-size slide

  33. [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
    ݱࡏࣥߦ౸ྃୈࡾߦ

    View full-size slide

  34. ෆੋ㑌ݸ஍ํ౎ೳதᏗ
    • ༗Ұࠣᔒ༗ࣥߦҙٛత஍ํੋෆೳதᏗతɻ૾ੋۭߦɼ
    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] తߦᏐແ๏தᏗ

    View full-size slide

  35. ࡏಛఆ৘گԼ break
    • ՄҎ୞༗ࡏಛఆత৘گԼ break

    • break [file:]line [if ]

    (byebug) break 3 if history[user_id]
    Created breakpoint 5 at /app/coupon.rb:3

    View full-size slide

  36. ࡏ rails server ༻ byebug
    • rails 4.2 ೭ޙब༬ઃࡏ։ᚙ໛ࣜ҆᧋ byebug

    • ࡏ code ཫ࢖༻ byebug method ိࡏࣥߦఔࣜత࣌ީఀࡏ
    byebug ႔ɻ

    • ඇ rails తఔࣜ require 'byebug' ޙ໵Մ༻ byebug
    methodɻ

    • ෆա byebug method ෆࢉੋதᏗᴍɻ

    View full-size slide

  37. ࡏ 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 తԼҰߦ

    View full-size slide

  38. ࡏඇ 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

    View full-size slide

  39. ᑍ݅ࣜ 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
    ୞༗ᑍ݅ූ߹࣌࠽தᏗ

    View full-size slide

  40. • ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ

    • ෆ֬ఆᏓᏐతᆴੋଟগɻ

    • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ

    • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ

    • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ
    ৗݟత debug ໰୊

    View full-size slide

  41. ༻ 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

    View full-size slide

  42. ༻ 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

    View full-size slide

  43. [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

    View full-size slide

  44. [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

    View full-size slide

  45. ᙛ࿨㚎ݐࢦྩিಥ࣌ɼ
    ࢖༻ 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}

    View full-size slide

  46. 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 ᏓᏐɻ

    View full-size slide

  47. [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

    View full-size slide

  48. ෆ୞᧺࡯ɼؐՄҎհೖ
    [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}"

    View full-size slide

  49. • ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ

    • ෆ֬ఆᏓᏐతᆴੋଟগɻ

    • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ

    • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ

    • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ
    ৗݟత debug ໰୊

    View full-size slide

  50. ༻ 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

    View full-size slide

  51. ༻ 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}

    View full-size slide

  52. display expr
    • ࡏ఍ୡ㑌ݸதᏗᴍత࣌ީɼ။ࣗಈࣥߦ exprɻ

    • expr ՄҎ༗෭࡞༻ɻdisplay x+=1 ။վᏓఔࣜཫ x తᆴɻ

    View full-size slide

  53. ༻ 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}

    View full-size slide

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

    • set nolinetrace ՄҎ᮫ᎃɻ

    View full-size slide

  55. ༻ 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}

    View full-size slide

  56. ༻ 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}

    View full-size slide

  57. ༻ 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}

    View full-size slide

  58. • ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ

    • ෆ֬ఆᏓᏐతᆴੋଟগɻ

    • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ

    • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ

    • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ
    ৗݟత debug ໰୊

    View full-size slide

  59. ౸ఈݺڣྃ䬟Ұஈఔࣜ?
    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"]

    View full-size slide

  60. ౸ఈݺڣྃ䬟Ұஈఔࣜ?
    # 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"]

    View full-size slide

  61. 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"]

    View full-size slide

  62. "ஶ໊"త 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])

    View full-size slide

  63. 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")

    View full-size slide

  64. ༻ 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)

    View full-size slide

  65. 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ɻ

    View full-size slide

  66. • ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ

    • ෆ֬ఆᏓᏐతᆴੋଟগɻ

    • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ

    • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ

    • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ
    ৗݟత debug ໰୊

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  73. 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

    View full-size slide

  74. • ෆ֬ఆ๭ஈఔࣜ။ෆ။ඃࣥߦ౸ɻ

    • ෆ֬ఆᏓᏐతᆴੋଟগɻ

    • ෆ֬ఆᏓᏐੋࡏ䬟ཫඃमվతɻ

    • ෆ֬ఆ౸ఈݺڣ౸ྃ䬟Ұஈఔࣜɻ

    • ෆ֬ఆ䬟ཫݺڣṜҰஈఔࣜɻ
    ৗݟత debug ໰୊

    View full-size slide

  75. 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]

    View full-size slide

  76. ݁࿦
    • byebug ՄҎ㢨ॿզ၇ߋշߋํศ஍ፙग़ఔࣜత໰୊ɻ

    • ՄҎ࢖༻ byebug ိڠॿզ၇ཧղఔࣜӡ࡞ɻಛผੋᯩଶ෼
    ੳᔒ㭎๏႔ཧత෦㟨ɻ

    View full-size slide

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

    View full-size slide