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

プロを目指す人のための例外処理(再)入門 / #rubykansai 2018-01-13

プロを目指す人のための例外処理(再)入門 / #rubykansai 2018-01-13

第80回 Ruby関西 勉強会の発表資料です。
https://rubykansai.doorkeeper.jp/events/69011

Junichi Ito

January 13, 2018
Tweet

More Decks by Junichi Ito

Other Decks in Technology

Transcript

  1. ϓϩΛ໨ࢦ͢ਓͷͨΊͷྫ֎ॲཧʢ࠶ʣೖ໳
    ҏ౻३Ұ (@jnchito)
    2018.01.13 ୈ80ճ Rubyؔ੢ ษڧձ

    View Slide

  2. About Me
    • ҏ౻३Ұ

    • RailsϓϩάϥϚ@SonicGarden

    • ϦϞʔτϫʔΧʔ

    • Ϊλʔ޷͖

    • Blog: give IT a try

    • Twitter: @jnchito

    View Slide

  3. ฌݿݝ੢࿬ࢢࡏॅʢग़਎͸େࡕ෎๛தࢢʣ

    View Slide

  4. everyday Rails
    RSpecʹΑΔRails
    ςετೖ໳
    Rails 5.1 + RSpec 3.6ʹ

    ۙ೔Ξοϓσʔτ༧ఆʂ

    View Slide

  5. ϓϩΛ໨ࢦ͢ਓͷ

    ͨΊͷRubyೖ໳
    ޷ධൃചதʂʂ

    View Slide

  6. ࠓ೔͓࿩͢͠Δ͜ͱ
    • ྫ֎ͱྫ֎ॲཧʹ͍͓ͭͯ͞Β͍
    • ຊ౰ʹ͋ͬͨා͍࿩
    • ྫ֎ॲཧͷόουϓϥΫςΟεˍϕετϓϥΫςΟε
    • ྫ֎ॲཧʢओʹઃܭʣʹؔ͢Δߴ౓ͳτϐοΫ
    • ۀ຿ΤϥʔͱγεςϜΤϥʔͷҧ͍
    • ྫ֎ॲཧͱϩʔϧόοΫͷؔ܎
    • ߈Ίͷྫ֎ʢҙਤతʹྫ֎Λൃੜͤ͞Δʣ

    View Slide

  7. ྫ֎ͱྫ֎ॲཧʹ͍͓ͭͯ͞Β͍

    View Slide

  8. ྫ֎ͱྫ֎ॲཧʹ͍͓ͭͯ͞Β͍
    • ྫ֎(Exception)ͱ͸
    • ͦΕҎ্ϓϩάϥϜΛଓߦͰ͖ͳ͍ྫ֎తͳঢ়گ
    • ࡶʹݴ͑͹ϓϩάϥϜͷΤϥʔ
    • ྫ֎ॲཧͱ͸
    • ൃੜͨ͠ྫ֎Λద੾ʹॲཧ͢Δ͜ͱ
    • ΤϥʔͱແԑͰ͍ΒΕΔϓϩάϥϜ͸ͳ͍
    • Αͬͯਖ਼͍͠ྫ֎ॲཧΛֶͿ͜ͱ͸ඇৗʹॏཁ

    View Slide

  9. Rubyʹ͓͚Δྫ֎ॲཧͷجຊߏจ
    begin
    # Τϥʔ͕ൃੜ͢Δ͔΋͠Εͳ͍ॲཧ
    a = 1 / 0
    rescue => e
    # Τϥʔ͕ى͖ͨ৔߹ͷॲཧ
    puts "Τϥʔ͕ൃੜ͠·ͨ͠: #{e.message}”
    end
    # ϝιουશମ͕ྫ֎ॲཧͷର৅ʹͳΔ৔߹͸begin/endΛলུͰ͖Δ
    def some_method
    1 / 0
    rescue ZeroDivisionError => e
    puts "ZeroDivisionError͕ൃੜ͠·ͨ͠: #{e.message}"
    end
    # ্ͷίʔυͱԼͷίʔυ͸ಉ͡
    def some_method
    begin
    1 / 0
    rescue ZeroDivisionError => e
    puts "ZeroDivisionError͕ൃੜ͠·ͨ͠: #{e.message}"
    end
    end

    View Slide

  10. ͨͩ͠ɺ͜ΕͰऴΘΔͱ΍͹͍
    • ʮϋϯϚʔΛ࣋ͭਓʹ͸͢΂͕ͯఝʹݟ͑Δʯ
    • ྫ֎ॲཧΛ֮͑ͨਓ͸ྫ֎ॲཧΛ࢖͍ͨ͘ͳΔ
    • Τϥʔ͕ى͖ͨΒrescue͢Ε͹͍͍ͱצҧ͍͢Δ
    • ͋ͬͪͬͪ͜ʹbegin/rescueΛຒΊࠐΉ
    • ʮΤϥʔʹڧ͍ϓϩάϥϜ͕Ͱ͖ͨYOʂʘ(^O^)ʗʯ
    • Ͱ͸͋Γ·ͤΜʂʂ!

    View Slide

  11. ຊ౰ʹ͋ͬͨා͍࿩

    View Slide

  12. ຊ౰ʹ͋ͬͨා͍࿩ʢલ৬Ͱͷମݧஊʣ
    • ͱ͋ΔWebγεςϜʢࣾ಺γεςϜʣΛड͚ܧ͍ͩ
    • ͦͷγεςϜ͸໰୊ͳ͘ಈ͍͍ͯͨʢΑ͏ʹݟ͑ͨʣ
    • γεςϜվमͷͨΊݱ৔ͷਓͱ࿩͢ػձΛ΋ͬͨ
    • ݱ৔ͷਓͷ࢖͍ํΛݟͤͯ΋Βͬͨ
    • อଘϘλϯΛΫϦοΫˠʮγεςϜΤϥʔ: -1ʯ
    • ๻ʮ͑ͬɺԿ͜Εʁʯ
    • ݱ৔ͷਓʮ͜Ε͕ग़ͨΒϘλϯΛ࠶ΫϦοΫ͠·͢ʯ

    View Slide

  13. Πϝʔδతʹ͸͜͏ʢ࣮ࡍ͸ASP.NETʣ
    • Τϥʔ͕ൃੜͨ͠ΒΤϥʔίʔυΛදࣔͯ͠ऴΘΓ
    • ௨஌΋͞Εͳ͍ɺϩάʹ΋·ͬͨ͘৘ใ͕࢒Βͳ͍
    • ݱ৔͸ʮΤϥʔ͕ग़ͨΒ࠶ΫϦοΫʯΛϚχϡΞϧԽ
    • ͦͷޙͷௐࠪˠઃܭϛεͰσουϩοΫ͕සൃͯͨ͠
    def create
    @post = Post.new(post_params)
    @post.save!
    redirect_to post_path(@post)
    rescue => e
    flash.now[:alert] = "γεςϜΤϥʔ: #{e.error_code}"
    render action: :new
    end

    View Slide

  14. ଞʹ΋͜Μͳͷͱ͔ʢ࣮ࡍ͸C#ʣ
    class PostService
    def find_data(id)
    # औಘͨ͠σʔλ͸ͳ͔ͥΠϯελϯεม਺ʹηοτ͞ΕΔ
    @data = Post.find(id)
    # ੒ޭ·ͨ͸ࣦഊΛ਺஋Ͱฦ͢
    return 1
    rescue => e
    # Τϥʔ͕ى͖ͨΒϝοηʔδ͚ͩ֨ೲͯ͠0Λฦ͢
    @error_message = e.message
    return 0
    end
    def save_data(data)
    # ΄͔ͷϝιου΋ಉ͡Α͏ͳྫ֎ॲཧ͕ॻ͔Ε͍ͯΔ
    end
    end
    # ҰԠ໭Γ஋͸ड͚औΔ͕ɺ1͔0ͷνΣοΫ͸͠ͳ͍
    ret = post_service.find_data(id)
    # Կ΋ߟ͑ͣʹσʔλΛऔͬͯ͘Δ
    post = post_service.data
    # औಘʹࣦഊͨ͠Βpost͸nilͳͷͰɺ͜͜ͰΤϥʔ͕ى͖Δ
    title = post.title

    View Slide

  15. ͜ͷ݅ͷڭ܇ͱྫ֎ॲཧͷجຊతͳߟ͑ํ
    • ྫ֎ॲཧ͸࢖͍ํΛؒҧ͑Δͱɺ֐ͷํ͕େ͖͘ͳΔ
    • Ͱ͖Δ͜ͱͱɺ΍͍͍ͬͯ͜ͱ͸ҟͳΔ
    • ྫ֎ॲཧͷجຊతͳߟ͑ํ
    • ૉਓ͸rescue͢Μͳʂʂ
    • Τϥʔ͕ग़ͨΒͦ͜ͰʓͶʂʂ
    • ྫ֎ॲཧ͸ϑϨʔϜϫʔΫͷڞ௨ॲཧʹ·͔ͤΖʂʂ

    View Slide

  16. ྫ֎ॲཧΛ࢖ͬͯ΋ڐ͞ΕΔέʔεɾͦͷ1
    • ଞͷ஥ؒΛಓͮΕʹͨ͘͠ͳ͍৔߹
    # ෳ਺ͷϢʔβʔʹҰׅͰϝʔϧΛૹ৴͢Δ
    users.each do |user|
    begin
    # ଞͷϢʔβʔΛಓͮΕʹ͠ͳ͍Α͏ɺΤϥʔ͕ى͖ͯ΋ଓߦ͢Δ
    send_mail_to(user)
    rescue => e
    puts "#{e.class}: #{e.message}"
    puts e.backtrace
    end
    end

    View Slide

  17. ྫ֎ॲཧΛ࢖ͬͯ΋ڐ͞ΕΔέʔεɾͦͷ2
    • ྫ֎ͷ༗ແͰ͔͠ཁ݅Λຬͨͤͳ͍৔߹
    require 'json'
    def valid_json_format?(text)
    # ࣮ࡍʹύʔεͯ͠Τϥʔ͕ൃੜ͢Δ͔Ͳ͏͔νΣοΫ͢Δ͔͠ͳ͍
    JSON.parse(text)
    true
    rescue JSON::ParserError
    false
    end
    valid_json_format?('{ "a": 1 }') #=> true
    valid_json_format?('{ "a": 1') #=> false

    View Slide

  18. ྫ֎ॲཧͷόουϓϥΫςΟε☠

    View Slide

  19. 1. ྫ֎ͷѲΓͭͿ͠☠
    • ୭΋Τϥʔʹؾ͔ͮͳ͍ɺ͋ͱͰௐࠪ΋Ͱ͖ͳ͍
    • ্ͷྫ͸ۃ୺͕ͩɺ݁Ռతʹແࢹ͞ΕΔ৔߹΋͋Δ
    • ໭Γ஋͕ແࢹ͞Εͨ৔߹ͳͲ
    user = build_user(data)
    # ൃੜͨ͠Τϥʔ͸׬શʹແࢹ͞ΕΔ
    begin
    save(user)
    rescue
    end
    # Կࣄ΋ͳ͔͔ͬͨͷΑ͏ʹॲཧΛଓߦ
    send_mail_to(user)

    View Slide

  20. 2. ExceptionΫϥεΛrescue͍ͯ͠Δ☠
    • StandardErrorҎԼΛัଊ͢Δͷ͕ਖ਼ղ
    begin
    save(user)
    rescue Exception => e
    # ԿΒ͔ͷΤϥʔॲཧ
    end
    ϓϩΛ໨ࢦ͢ਓͷͨΊͷRubyೖ໳

    ୈ9ষʹొ৔͢Δਤ

    View Slide

  21. ࢀߟ
    # ໌ࣔతʹStandardErrorΛࢦఆ͢Δ
    begin
    save(user)
    rescue StandardError => e
    # ԿΒ͔ͷΤϥʔॲཧ
    end
    # ྫ֎ΫϥεΛࢦఆ͠ͳ͚Ε͹StandardErrorͱͦͷαϒΫϥε͕rescue͞ΕΔ
    begin
    save(user)
    rescue => e
    # ԿΒ͔ͷΤϥʔॲཧ
    end
    • ্ͷ2ͭ͸΍͍ͬͯΔ͜ͱ͸ಉ͡
    • ͳͷͰɺԼͷΑ͏ʹStandardError͸লུ͢Ε͹ྑ͍

    View Slide

  22. 3-1. begin͔Βrescue·Ͱͷൣғ͕ແବʹ޿͍☠
    • Ͳ͜Ͱൃੜ͢ΔΤϥʔΛัଊ͍ͨ͠ͷ͔Θ͔Βͳ͍
    # ฏ੒ͷ೔෇จࣈྻΛDateΦϒδΣΫτʹม׵͢Δ
    def convert_heisei_to_date(heisei_text)
    begin
    m = heisei_text.match(/ฏ੒(?\d+)೥(?\d+)݄(?\d+)೔/)
    year = m[:jp_year].to_i + 1988
    month = m[:month].to_i
    day = m[:day].to_i
    Date.new(year, month, day)
    rescue
    # ྫ֎͕ى͖ͨΒʢʹແޮͳ೔෇͕౉͞ΕͨΒʣnilΛฦ͍ͨ͠
    nil
    end
    end
    }
    {

    View Slide

  23. 3-2. rescueઅʹྫ֎ΫϥεΛԿ΋ࢦఆ͠ͳ͍☠
    • λΠϓϛε͕ݪҼͰൃੜͨ͠ྫ֎΋ัଊ͞Εͯ͠·͏
    # ฏ੒ͷ೔෇จࣈྻΛDateΦϒδΣΫτʹม׵͢Δ
    def convert_heisei_to_date(heisei_text)
    begin
    m = heisei_text.match(/ฏ੒(?\d+)೥(?\d+)݄(?\d+)೔/)
    year = m[:jp_year].to_i + 1988
    month = m[:month].to_i
    day = m[:day].to_i
    Date.new(year, month, day)
    rescue
    # ྫ֎͕ى͖ͨΒʢʹແޮͳ೔෇͕౉͞ΕͨΒʣnilΛฦ͍ͨ͠
    nil
    end
    end

    View Slide

  24. 4. ྫ֎ॲཧΛςετ͠ͳ͍☠
    • ؊৺ͷຊ൪؀ڥͰॳΊͯྫ֎ॲཧͷόάʹؾͮ͘
    • ΋ͱ΋ͱൃੜ͍ͯͨ͠ΤϥʔͷݪҼ͕ࣦΘΕͯ͠·͏
    • લ৬Ͱܦݧ͋ΓʢҾ͖ܧ͍ͩγεςϜͰɾɾɾʣ
    def some_method
    1 / 0
    rescue => e
    # messageͱॻͭ͘΋Γ͕mesageͱॻ͍ͯ͠·ͬͨ
    puts "Τϥʔ͕ൃੜ͠·ͨ͠: #{e.mesage}"
    puts e.backtrace
    end

    View Slide

  25. ωοτͷهࣄʹ͸ཁ஫ҙ
    • όουϓϥΫςΟεΛ঺հ͍ͯ͠Δهࣄ΋ଟ͍
    • ͦΜͳهࣄͰ΋άάͬͨͱ͖ʹ্Ґʹग़͖ͯͯ͠·͏
    • ExceptionΛrescueͯ͠Δهࣄͱ͔ɺΑ͘ݟ͔͚Δ
    • ͦΜͳهࣄΛӏವΈʹ͠ͳ͍Α͏ʹʂ

    View Slide

  26. ྫ֎ॲཧͷϕετϓϥΫςΟε

    View Slide

  27. 1. ݪଇͱͯ͠rescue͠ͳ͍
    • ྫ֎ॲཧͷجຊతͳߟ͑ํʢ࠶ܝʣ
    • ૉਓ͸rescue͢Μͳʂʂ
    • Τϥʔ͕ग़ͨΒͦ͜ͰʓͶʂʂ
    • ྫ֎ॲཧ͸ϑϨʔϜϫʔΫͷڞ௨ॲཧʹ·͔ͤΖʂʂ
    • Ҏ߱͸rescue͕Ͳ͏ͯ͠΋ඞཁͳঢ়گΛ૝ఆ

    View Slide

  28. 2. ྫ֎ͷ৘ใΛϩάʹ࢒͢ˍ௨஌͢Δ
    • ྫ֎Ϋϥε໊ɺϝοηʔδɺόοΫτϨʔεΛϩάग़ྗ
    • Bugsnag΍RollbarɺErrbitͳͲͰ։ൃऀʹ௨஌͢Δ
    • Τϥʔʹ͙͢ؾ͖ͮɺ͙͢ௐࠪͰ͖ΔΑ͏ʹ͢Δ
    begin
    save(user)
    rescue => e
    # ϩάʹ࢒͢
    logger.error "#{e.class} / #{e.message}"
    logger.error e.backtrace.join("\n")
    # ௨஌͢Δ
    Bugsnag.notify(e)
    end

    View Slide

  29. 3. ྫ֎ॲཧͷର৅ൣғͱର৅ΫϥεΛߜΓࠐΉ
    • ัଊ͍ͨ͠Τϥʔ͚ͩΛ࣮֬ʹૂ͍ܸͪ͢Δ
    • ͦΕҎ֎ͷΤϥʔ͕ग़ͨΒଈɺҟৗऴྃͤ͞Δ
    def convert_heisei_to_date(heisei_text)
    m = heisei_text.match(/ฏ੒(?\d+)೥(?\d+)݄(?\d+)೔/)
    year = m[:jp_year].to_i + 1988
    month = m[:month].to_i
    day = m[:day].to_i
    # ྫ֎ॲཧͷൣғΛڱΊɺัଊ͢Δྫ֎ΫϥεΛݶఆ͢Δ
    begin
    Date.new(year, month, day)
    rescue ArgumentError
    # ແޮͳ೔෇Ͱ͋Ε͹nilΛฦ͢
    nil
    end
    end

    View Slide

  30. ࢀߟ
    • ྫ֎ॲཧΛ࢖ΘͣʹࡁΉํ๏͕͋Ε͹ͦΕΛ࢖͏΂͖
    def convert_heisei_to_date(heisei_text)
    m = heisei_text.match(/ฏ੒(?\d+)೥(?\d+)݄(?\d+)೔/)
    year = m[:jp_year].to_i + 1988
    month = m[:month].to_i
    day = m[:day].to_i
    # ྫ֎ॲཧͰ͸ͳ͘ɺ৚݅෼ذΛ࢖͏
    if Date.valid_date?(year, month, day)
    Date.new(year, month, day)
    end
    end

    View Slide

  31. 4. ྫ֎ॲཧ΋ςετ͢Δ
    • ྫ֎ॲཧͷڍಈΛ֬ೝͰ͖ΔςετίʔυΛॻ͘
    • ࠶ݱ͕೉͍͠৔߹͸ϞοΫΛ׆༻͢Δ
    def some_method
    1 / 0
    rescue => e
    puts "Τϥʔ͕ൃੜ͠·ͨ͠: #{e.message}"
    puts e.backtrace
    end
    class SampleTest < Minitest::Test
    def test_some_method
    assert_output /Τϥʔ͕ൃੜ͠·ͨ͠/ do
    some_method
    end
    end
    end

    View Slide

  32. ྫ֎ॲཧʢओʹઃܭʣʹؔ͢Δߴ౓ͳτϐοΫ

    View Slide

  33. 1. ۀ຿ΤϥʔͱγεςϜΤϥʔͷҧ͍

    View Slide

  34. Τϥʔʹ͸2छྨͷΤϥʔ͕͋Δ
    • ۀ຿ΤϥʔʢϏδωεྫ֎ʣ
    • ೖྗϑΥʔϜʹ͓͚ΔϢʔβʔͷೖྗϛε
    • ݖݶҧ൓ʢݖݶͷͳ͍ϖʔδ΁ͷΞΫηε౳ʣ
    • γεςϜΤϥʔʢٕज़తྫ֎ʣ
    • ϓϩάϥϜͷϛεʢ͍ΘΏΔόάʣ
    • ωοτϫʔΫΤϥʔɺσʔλϕʔεͷμ΢ϯ౳
    • ։ൃऀ͸͜ͷ۠ผΛ෇͚ͳͯ͘͸ͳΒͳ͍

    View Slide

  35. ۀ຿Τϥʔ΁ͷରॲʢը໘ઃܭʣ
    • Ϣʔβʔʹ΍Γ௚ͤ͠͞Δʢ͓લ͕ѱ͍ͱ఻͑Δʣ

    View Slide

  36. ۀ຿Τϥʔ΁ͷରॲʢ಺෦ઃܭɾͦͷ1ʣ
    • ྫ֎ॲཧ͸ݪଇͱͯ͠࢖Θͳ͍
    • ੒ޭ or ࣦഊ͸ϝιουͷ໭Γ஋Ͱදݱ͢Δ
    • ݺͼग़͠ଆ͸ඞͣ໭Γ஋Λݕূ͢Δ
    def create
    @event = Event.new(event_params)
    # saveϝιουͷ໭Γ஋ΛνΣοΫ
    if @event.save
    # ໭Γ஋͕trueͳͷͰ੒ޭ
    redirect_to @event, notice: 'Event was successfully created.'
    else
    # ໭Γ஋͕falseͳͷͰࣦഊ
    render :new
    end
    end

    View Slide

  37. ۀ຿Τϥʔ΁ͷରॲʢ಺෦ઃܭɾͦͷ2ʣ
    • ෆඞཁʹྫ֎ॲཧΛ࢖Θͳ͍͜ͱ
    • ྫ֎ॲཧΛͳͯ͘͠΋ۀ຿ΤϥʔʹରॲͰ͖Δ͔ʁ
    • NOͳΒॲཧϑϩʔͷ੍ޚʹྫ֎ॲཧΛ࢖͍ͬͯΔ
    # ϓϩδΣΫτͷશؔ܎ऀʹରͯ͠కΊ੾ΓͷมߋΛࢼΈΔϝιου
    def extend_deadline_for_all_stakeholders(project, new_deadline)
    project.developers.each do |developer|
    developer.update!(deadline: new_deadline)
    end
    project.customer.update!(deadline: new_deadline)
    project.manager.update!(deadline: new_deadline)
    true
    rescue ActiveRecord::RecordInvalid
    # ۀ຿Τϥʔͳͷʹྫ֎ॲཧΛ࢖͍ͬͯΔʢNGʣ
    false
    end

    View Slide

  38. ࢀߟ
    • ྫ֎ॲཧΛ࢖Θͣʹ࣮૷͢Δ৔߹ͷίʔυྫ
    def extend_deadline_for_all_stakeholders(project, new_deadline)
    all_success = true
    project.developers.each do |developer|
    all_success &= developer.update(deadline: new_deadline)
    end
    all_success &= project.customer.update(deadline: new_deadline)
    all_success &= project.manager.update(deadline: new_deadline)
    # ্ͷॲཧͰ1ͭͰ΋false͕ฦΕ͹ɺall_success͸falseʹมΘΔ
    # ʢຊདྷ͸σʔλϕʔετϥϯβΫγϣϯͷϩʔϧόοΫ΋ߟྀ͢΂͖ɻৄࡉ͸ޙड़ʣ
    all_success
    end

    View Slide

  39. γεςϜΤϥʔ΁ͷରॲʢը໘ઃܭʣ
    • ͝ΊΜɺͬͪ͜Ͱରॲ͢Δ͔Β଴ͬͯͯɺͱ఻͑Δ
    • ͍ΘΏΔ500Τϥʔը໘Λදࣔ͢Δ

    View Slide

  40. γεςϜΤϥʔ΁ͷରॲʢ಺෦ઃܭʣ
    • ݪଇ͸Կ΋͠ͳ͍
    • ଈ࠲ʹۓٸఀࢭͤ͞ɺڞ௨ॲཧʹ·͔ͤΔ
    • ΍ΉΛಘͳ͍৔߹ͷΈɺrescueͯ͠ଓߦ͢Δ
    • ΋ͪΖΜϩάग़ྗ΍௨஌͸ඞਢʂ

    View Slide

  41. 2. ྫ֎ॲཧͱϩʔϧόοΫͷؔ܎

    View Slide

  42. ྫ֎ॲཧͱϩʔϧόοΫͷؔ܎
    • ʮΞτϛοΫૢ࡞͸Կ͔ʯΛৗʹҙࣝ͢Δ
    • ΞτϛοΫૢ࡞ʢෆՄ෼ૢ࡞ʣͱ͸
    • શͯͷมߋ͕੒ޭͨ͠ͱ͖ͷΈɺมߋΛ֬ఆ
    • 1ͭͰ΋ࣦഊ͢Ε͹શ෦ΩϟϯηϧʢϩʔϧόοΫʣ
    • ྫ
    • ෳ਺ͷϨίʔυΛಉ࣌ʹߋ৽͢Δ৔߹
    • σʔλϕʔεߋ৽ޙʹ՝ܾۚࡁAPIΛݺͼग़͢৔߹

    View Slide

  43. RailsͰෳ਺ͷϨίʔυΛಉ࣌ʹߋ৽͢Δ৔߹
    • transactionϝιουͱRollbackྫ֎Λ׆༻͢Δ
    • γεςϜΤϥʔ͕ى͖ͨΒͦ͜ͰϩʔϧόοΫ
    • ۀ຿ΤϥʔͳΒRollbackྫ֎Ͱ໌ࣔతʹϩʔϧόοΫ
    def extend_deadline_for_all_stakeholders(project, new_deadline)
    all_success = true
    transaction do
    project.developers.each do |developer|
    all_success &= developer.update(deadline: new_deadline)
    end
    all_success &= project.customer.update(deadline: new_deadline)
    all_success &= project.manager.update(deadline: new_deadline)
    unless all_success
    # ໌ࣔతʹϩʔϧόοΫͤ͞Δʢtransactionϝιου͕rescue͢ΔͷͰॲཧ͸ଓߦ͞ΕΔʣ
    raise ActiveRecord::Rollback
    end
    end
    all_success
    end
    ]
    [

    View Slide

  44. 3. ߈Ίͷྫ֎ʢҙਤతʹྫ֎Λൃੜͤ͞Δʣ

    View Slide

  45. ߈Ίͷྫ֎ ͦͷ1: ༧ظͤ͵৚݅෼ذΛ͢
    • ༧ظͤ͵৚݅෼ذʹೖͬͨΒྫ֎Λൃੜͤ͞Δ
    • ࢮ͵͸ͣͷϓϩάϥϜΛແཧʹੜ͔ͯ͠͸͍͚ͳ͍
    # elseʹೖͬͨΒྫ֎Λൃੜͤ͞Δύλʔϯʢྑ͍ྫʣ
    def currency_of(country)
    case country
    when :japan
    'yen'
    when :us
    'dollar'
    when :india
    'rupee'
    else
    raise ArgumentError, "ແޮͳࠃ໊Ͱ͢ɻ#{country}"
    end
    end
    # ྫ֎͕ൃੜ͢Δ
    currency_of(:italy) #=> ArgumentError: ແޮͳࠃ໊Ͱ͢ɻitaly

    View Slide

  46. ࢀߟ: ࢮ͵͸ͣͳͷʹɺࢮͳͳ͍έʔεɾͦͷ1
    • else͕ͳ͍ → nil͕ฦͬͯ͠·͏
    # elseΛ༻ҙ͠ͳ͍ύλʔϯʢྑ͘ͳ͍ྫʣ
    def currency_of(country)
    case country
    when :japan
    'yen'
    when :us
    'dollar'
    when :india
    'rupee'
    end
    end
    # ૝ఆ֎ͷࠃ໊Λ౉͢ͱnil͕ฦΔ
    currency = currency_of(:italy)
    #=> nil
    # ༧ظͤ͵λΠϛϯάͰΤϥʔ͕ൃੜ͢Δ
    currency.upcase
    #=> NoMethodError: undefined method `upcase' for nil:NilClass

    View Slide

  47. ࢀߟ: ࢮ͵͸ͣͳͷʹɺࢮͳͳ͍έʔεɾͦͷ2
    • elseͰಛఆͷ஋Λฦ͢ → ໃ६ͨ͠஋͕ฦͬͯ͠·͏
    # elseΛ:indiaͱͯ͠ѻ͏ύλʔϯʢྑ͘ͳ͍ྫʣ
    def currency_of(country)
    case country
    when :japan
    'yen'
    when :us
    'dollar'
    else
    'rupee'
    end
    end
    # ໃ६ͨ͠஋͕ฦ͖ͬͯͯ͠·͏
    country = :italy
    currency = currency_of(country)
    #=> “rupee”
    price = 100
    "#{country}: #{price}#{currency}"
    #=> "italy: 100rupee"

    View Slide

  48. ߈Ίͷྫ֎ ͦͷ2: ͋Γಘͳ͍Τϥʔʹ͸ڧؾͰ
    • ۀ຿Τϥʔ͢ΒγεςϜΤϥʔͱݟͳͤΔ৔߹΋͋Δ
    • ͦ͏͍͏έʔεͰ͸save!΍update!Λ࢖͏
    • ͨͩ͠ɺΞτϛοΫૢ࡞͚ͩ͸ҡ࣋͢ΔΑ͏ʹ
    def extend_deadline_for_all_stakeholders(project, new_deadline)
    # ສҰͷࣄଶʹ͸උ͓͑ͯ͘ʢσʔλϕʔε΁ͷมߋΛΞτϛοΫૢ࡞ʹ͢Δʣ
    transaction do
    # ୭Ұਓͱͯ͠కΊ੾ΓͷԆ௕ʹ͸จ۟ΛݴΘͳ͍͸ͣͩʂʢจ۟ΛݴΘΕͨΒγεςϜΤϥʔʣ
    project.developers.each do |developer|
    developer.update!(deadline: new_deadline)
    end
    project.customer.update!(deadline: new_deadline)
    project.manager.update!(deadline: new_deadline)
    end
    end

    View Slide

  49. ·ͱΊ

    View Slide

  50. ·ͱΊ: ਖ਼͍͠ྫ֎ॲཧͰ޾ͤͳਓੜΛ̇
    • ྫ֎ͱྫ֎ॲཧʹ͍͓ͭͯ͞Β͍
    • ຊ౰ʹ͋ͬͨා͍࿩
    • ྫ֎ॲཧͷόουϓϥΫςΟεˍϕετϓϥΫςΟε
    • ྫ֎ॲཧʢओʹઃܭʣʹؔ͢Δߴ౓ͳτϐοΫ
    • ۀ຿ΤϥʔͱγεςϜΤϥʔͷҧ͍
    • ྫ֎ॲཧͱϩʔϧόοΫͷؔ܎
    • ߈Ίͷྫ֎ʢҙਤతʹྫ֎Λൃੜͤ͞Δʣ

    View Slide

  51. ࢀߟจݙ
    • .NETͷྫ֎ॲཧ Part.1ʢ@nakama00ɺ2008೥ʣ
    • ྫ֎ઃܭʹ͓͚Δେࡑʢ@t_wadaɺ2012೥ʣ
    • RailsΞϓϦέʔγϣϯʹ͓͚ΔΤϥʔॲཧʢྫ֎ઃܭʣͷߟ͑ํʢ@jnchitoʣ
    • give IT a tryʢ@jnchitoʣ
    • Nasty design can blast your brain!ʢ2010೥3݄31೔ʣ
    • ٕज़ॻ௥Ճͦͷ2ʢ2010೥4݄10೔ʣ
    • and…

    View Slide

  52. ϓϩΛ໨ࢦ͢ਓͷ

    ͨΊͷRubyೖ໳
    ୈ9ষ ྫ֎ॲཧΛཧղ͢Δ

    View Slide

  53. @jnchito
    blog.jnito.com
    'PMMPXNF

    View Slide