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

銀座Rails版 「Rubyプログラミング問題に チャレンジ!」公開コードレビュー / ginzarails code review

Junichi Ito
January 25, 2022

銀座Rails版 「Rubyプログラミング問題に チャレンジ!」公開コードレビュー / ginzarails code review

銀座Rails#41で使用したスライドです。
https://ginza-rails.connpass.com/event/234304/

- Links -

全視情協:点字とは - 点字のしくみ
http://www.naiiv.net/braille/?tenji-sikumi

点字 - Wikipedia
https://ja.wikipedia.org/wiki/点字

レビュー対象のプルリクエスト
https://github.com/JunichiIto/tenji-maker-challenge-for-ginza-rails/pull/5

Rubyプログラミング問題にチャレンジ! -改訂版・チェリー本発売記念- Advent Calendar 2021
https://qiita.com/advent-calendar/2021/ruby-challenge

Qiitaアドベントカレンダーの最優秀作品
https://qiita.com/haruguchiyuma/items/7d93a8feca11a325bee9

出題者(@jnchito)の模範解答
https://github.com/JunichiIto/tenji-maker-challenge-for-ginza-rails/tree/answer

辛口バージョンのテストパターン
https://gist.github.com/JunichiIto/1c8565bbffd0b5cf589b905f9ad2388f

辛口バージョンの模範解答
https://github.com/JunichiIto/tenji-maker-challenge-for-ginza-rails/blob/karakuchi-answer/lib/tenji.rb

プロを目指す人のためのRuby入門 [改訂2版]
https://gihyo.jp/book/2021/978-4-297-12437-3

Rubyコミッタ辻本さんによる推薦の言葉
https://twitter.com/k_tsj/status/1469535631995191303

Twitter
https://twitter.com/jnchito

Blog
https://blog.jnito.com/

第2回 ツクってアソぶハッカソン
https://tsukuaso.connpass.com/event/234370/

Everyday Rails - RSpecによるRailsテスト入門
https://leanpub.com/everydayrailsrspec-jp/

Junichi Ito

January 25, 2022
Tweet

More Decks by Junichi Ito

Other Decks in Technology

Transcript

  1. ۜ࠲Rails#41 2022-1-25
    ۜ࠲Rails൛
    ʮRubyϓϩάϥϛϯά໰୊ʹ
    νϟϨϯδʂʯެ։ίʔυϨϏϡʔ
    ҏ౻ ३Ұ / @jnchito

    View full-size slide

  2. ͜ͷൃද͸ԿͰ͔͢ʁ
    • Έͳ͞Μ͕ॻ͍ͯ͘ΕͨϓϩάϥϜΛίʔυϨϏϡʔ͠·͢

    • ϓϩάϥϜͷ͓୊͸ʮ఺ࣈϝʔΧʔϓϩάϥϜʯͰ͢

    • QiitaΠϕϯτͷ࠷༏ल࡞඼΍๻ͷ໛ൣղ౴΋͓ݟͤ͠·͢

    View full-size slide

  3. ఺ࣈϝʔΧʔϓϩάϥϜʁ

    View full-size slide

  4. ఺ࣈϝʔΧʔϓϩάϥϜͱ͸
    • ೖྗʹϩʔϚࣈɺग़ྗʹ఺ࣈʢͷจࣈྻʣͱͳΔRubyϓϩάϥϜͰ͢
    tenji_maker = TenjiMaker.new
    puts tenji_maker.to_tenji('A HI RU')
    ↑ɹ↑ɹ↑

    ͋ ͻ Δ
    #=> o- o- oo
    # -- o- -o
    # -- oo --

    View full-size slide

  5. ͸͍ɺઌੜʂ


    ఺ࣈͷ͘͠Έ͕Θ͔Γ·ͤΜʂ

    View full-size slide

  6. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ఺ࣈʹ͸6ͭͷ఺͕͋ΓɺͦΕͧΕ1ʙ6ͷ൪߸͕ৼΒΕ͍ͯ·͢
    ᶃ ᶆ

    ᶄ ᶇ

    ᶅ ᶈ

    View full-size slide

  7. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ʮ͍͋͏͓͑ʯ͸͜͏Ͱ͢ʢ͜Ε͸֮͑Δ͚ͩʣ
    ᶃ ʔ

    ʔ ʔ

    ʔ ʔ
    ᶃ ʔ

    ᶄ ʔ

    ʔ ʔ
    ᶃ ᶆ

    ʔ ʔ

    ʔ ʔ
    ᶃ ᶆ

    ᶄ ʔ

    ʔ ʔ
    ʔ ᶆ

    ᶄ ʔ

    ʔ ʔ
    ͋ɹɹ͍ɹɹ͏ɹɹ͑ɹɹ͓

    View full-size slide

  8. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ʮ͔͖͚͘͜ʯ͸ʮ͍͋͑͏͓ʯʹᶈͷ఺ΛՃ͑·͢
    ᶃ ʔ

    ʔ ʔ

    ʔ ᶈ
    ᶃ ʔ

    ᶄ ʔ

    ʔ ᶈ
    ᶃ ᶆ

    ʔ ʔ

    ʔ ᶈ
    ᶃ ᶆ

    ᶄ ʔ

    ʔ ᶈ
    ʔ ᶆ

    ᶄ ʔ

    ʔ ᶈ
    ͔ɹɹ͖ɹɹ͘ɹɹ͚ɹɹ͜

    View full-size slide

  9. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ʮͤͦ͢͞͠ʯ͸ʮ͍͋͑͏͓ʯʹᶇͱᶈͷ఺ΛՃ͑·͢
    ᶃ ʔ

    ʔ ᶇ

    ʔ ᶈ
    ᶃ ʔ

    ᶄ ᶇ

    ʔ ᶈ
    ᶃ ᶆ

    ʔ ᶇ

    ʔ ᶈ
    ᶃ ᶆ

    ᶄ ᶇ

    ʔ ᶈ
    ʔ ᶆ

    ᶄ ᶇ

    ʔ ᶈ
    ͞ɹɹ͠ɹɹ͢ɹɹͤɹɹͦ

    View full-size slide

  10. ͳΜͱͳ͘Θ͔͖ͬͯͨʁ

    View full-size slide

  11. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ͨߦɺͳߦɺ͸ߦɺ·ߦɺΒߦ͸ʮ͍͋͏͓͑ʯʹ྘ͷ఺ΛՃ͑Ε͹OK

    View full-size slide

  12. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ʮ΍ΏΑʯ͸฼ԻΛҰ൪ԼʹԼΖͯ͠ɺᶆͷ఺ΛՃ͑·͢
    ᶃ ʔ

    ʔ ʔ

    ʔ ʔ
    ᶃ ᶆ

    ʔ ʔ

    ʔ ʔ
    ʔ ᶆ

    ᶄ ʔ

    ʔ ʔ
    ͋ɹɹɹɹɹ͏ɹɹɹɹɹ͓

    View full-size slide

  13. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ʮ΍ΏΑʯ͸฼ԻΛҰ൪ԼʹԼΖͯ͠ɺᶆͷ఺ΛՃ͑·͢
    ʔ ʔ

    ʔ ʔ

    ᶅ ʔ
    ʔ ʔ

    ʔ ʔ

    ᶅ ᶈ
    ʔ ʔ

    ʔ ᶇ

    ᶅ ʔ

    View full-size slide

  14. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ʮ΍ΏΑʯ͸฼ԻΛҰ൪ԼʹԼΖͯ͠ɺᶆͷ఺ΛՃ͑·͢
    ʔ ᶆ

    ʔ ʔ

    ᶅ ʔ
    ʔ ᶆ

    ʔ ʔ

    ᶅ ᶈ
    ʔ ᶆ

    ʔ ᶇ

    ᶅ ʔ
    ΍ɹɹɹɹɹΏɹɹɹɹɹΑ

    View full-size slide

  15. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ʮΘʯ͸ʮ͋ʯΛҰ൪ԼʹԼΖ͚ͩ͢ɻʮΜʯ͸ᶅᶇᶈͰද͠·͢
    ᶃ ʔ

    ʔ ʔ

    ʔ ʔ
    ʔ ʔ

    ʔ ᶇ

    ᶅ ᶈ
    ͋ɹɹɹɹɹΜɹɹɹɹɹΑ

    View full-size slide

  16. 2෼ͰΘ͔Δ఺ࣈͷ࢓૊Έ
    • ʮΘʯ͸ʮ͋ʯΛҰ൪ԼʹԼΖ͚ͩ͢ɻʮΜʯ͸ᶅᶇᶈͰද͠·͢ɻ
    ʔ ʔ

    ʔ ʔ

    ᶅ ʔ
    ʔ ʔ

    ʔ ᶇ

    ᶅ ᶈ
    ΘɹɹɹɹɹΜɹɹɹɹɹΑ

    View full-size slide

  17. ҎԼͷ఺ࣈ͸ࠓճ ม׵ର৅֎
    • ʮΛʯ

    • ௕Իʢ৳͹͢ԻɻʮͪʔͨʔʯͳͲʣ

    • ଅԻʢ͍ͪ͞ͳʮͭʯɻʮ͔ͬͺʯͳͲʣ

    • ୙Իʢʮ͕͙͗͛͝ʯͳͲʣɺ൒୙Իʢʮͺͽ΀΃Άʯʣ

    • ፠Իʢʮ͖Ό͖Ύ͖ΐʯͳͲʣ

    • ͳͲͳͲ

    View full-size slide

  18. ࢀߟจݙ͓Αͼը૾ͷҾ༻ݩ
    • શࢹ৘ڠ:఺ࣈͱ͸ - ఺ࣈͷ͘͠Έ

    http://www.naiiv.net/braille/?tenji-sikumi

    • ఺ࣈ - Wikipedia

    https://ja.wikipedia.org/wiki/఺ࣈ

    View full-size slide

  19. ͸͍ɺ΋͏఺ࣈΛϚελʔ


    ͠·ͨ͠Ͷʁʢॴཁ࣌ؒ2෼ʣ

    View full-size slide

  20. ೖྗ͢ΔϩʔϚࣈͷϧʔϧ
    • ͢΂ͯΞϧϑΝϕοτͷେจࣈͰॻ͘

    • ͔ͳͷؒ͸൒֯εϖʔεͰ۠੾Δ
    A HI RU
    [
    [

    View full-size slide

  21. ೖྗ͢ΔϩʔϚࣈͷϧʔϧ
    • ܇ྩࣜͰೖྗ͢ΔʢϔϘϯࣜ͸ߟྀෆཁʣ
    ܇ྩࣜ ϔϘϯࣜ
    ͠ SI SHI
    ͪ TI CHI
    ͭ TU TSU
    ; HU FU
    Μ N N/M

    View full-size slide

  22. ೖྗςΩετͷྫ
    • ͋ͻΔ = A HI RU
    • ͖ΓΜ = KI RI N
    • ͠·͏· = SI MA U MA
    • ʹΘͱΓ = NI WA TO RI
    • ͻΑ͜ = HI YO KO
    • ͖ͭͶ = KI TU NE
    • ҟৗͳೖྗ஋Λߟྀ͢Δඞཁ͸͋Γ·ͤΜ

    View full-size slide

  23. ࡞੒ͨ͠ϓϩάϥϜͷఏग़ํ๏
    • GitHubͷ਽ܗϦϙδτϦΛϑΥʔΫ͠ɺίʔυΛॻ͘

    • ϓϧϦΫΤετΛ࡞੒͠ɺCIͷςετ͕શ෦ύεͨ͠ΒOK
    class TenjiMakerTest < Minitest::Test
    def setup
    @tenji_maker = TenjiMaker.new
    end
    def test_a_hi_ru
    tenji = @tenji_maker.to_tenji('A HI RU')
    assert_equal <<~TENJI.chomp, tenji
    o- o- oo
    -- o- -o
    -- oo --
    TENJI
    end
    # ҎԼɺςετ͕ଓ͘

    View full-size slide

  24. ͜ͷߨԋͰֶΜͰ΄͍͜͠ͱ
    • ࣗ෼͕ॻ͍ͨίʔυͱଞͷਓ͕ॻ͍ͨίʔυΛݟൺ΂ͯΈΑ͏

    • ͍ΖΜͳϩδοΫͷߟ͑ํΛֶ΅͏

    • Rubyͷݴޠػೳ΍ศརͳϝιουʹֶ͍ͭͯ΅͏

    • ͜͜ͰֶΜͩ಺༰Λ໌೔͔Βॻࣗ͘෼ͷίʔυʹ׆͔ͯ͠ΈΑ͏

    View full-size slide

  25. ຊ೔ͷ͓͠ͳ͕͖
    • ࢀՃऀͷԠื࡞඼Λެ։ίʔυϨϏϡʔ ʢ1ຊʣ

    • QiitaΞυϕϯτΧϨϯμʔͰͷ࠷༏ल࡞඼Λ঺հ

    • ग़୊ऀʢ@jnchitoʣͷ໛ൣղ౴Λ঺հ

    View full-size slide

  26. ؍ઓπΠʔτ΋͓଴͍ͪͯ͠·͢ʂ
    • ʮ͜ͷίʔυɺ޷͖ʂʯͱ͔ʮ๻ͩͬͨΒ͜͏ॻ͘ͳ͋ʯͳͲͳͲ

    • Έͳ͞ΜͷπΠʔτ΋͜ͷൃදͷҰ෦Ͱ͢

    • ΈΜͳͰΘ͍Θ͍ίʔυϨϏϡʔ͠·͠ΐ͏😄

    • ͜ͷ͋ͱͷ࠙਌ձͰʮྑ͍ίʔυʯʹ͍ͭͯٞ࿦ͯ͠ΈΔͷ΋͍͍͔΋

    View full-size slide

  27. Ԡื࡞඼ͷެ։ίʔυϨϏϡʔ

    View full-size slide

  28. Ԡื࡞඼ͷެ։ίʔυϨϏϡʔ
    • ࠓ͔ΒϨϏϡʔର৅ͷϓϧϦΫΤετΛ1ຊબͼ·͢

    • બఆج४͸όΠτ਺ͷ߹ܭ͕࠷΋খ͍͞ϓϩάϥϜͰ͢ʂʢςετίʔυΛআ͘ʣ

    View full-size slide

  29. ͱ͍͏Θ͚Ͱɺຊ೔ͷର৅࡞඼͸ͪ͜Βʂ
    • https://github.com/JunichiIto/tenji-maker-challenge-for-ginza-rails/pull/5

    View full-size slide

  30. ϨϏϡʔ͓ΘΓ
    pofkuma͞ΜɺͲ͏΋͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ

    View full-size slide

  31. QiitaΞυϕϯτΧϨϯμʔͷ


    ࠷༏ल࡞඼ͷ঺հ

    View full-size slide

  32. QiitaΞυϕϯτΧϨϯμʔͷ࠷༏ल࡞඼
    • QiitaͷاըͰ΋ಉ͓͡୊ͰɺίʔυͱղઆهࣄΛॻ͍ͯ΋Β͍·ͨ͠

    https://qiita.com/advent-calendar/2021/ruby-challenge

    View full-size slide

  33. QiitaΞυϕϯτΧϨϯμʔͷ࠷༏ल࡞඼
    • Qiitaͷ࠷༏ल࡞඼͸ @haruguchiyuma ͞ΜͷίʔυͰ͢ʂ

    https://qiita.com/haruguchiyuma/items/7d93a8feca11a325bee9

    View full-size slide

  34. ๻ͷධՁϙΠϯτʢදজཧ༝ʣ
    • ίʔυ͕γϯϓϧͰ୹͘·ͱ·͍ͬͯΔ

    • ίʔυͷॻ͖ํʹΫη͕ͳ͘ಡΈ΍͍͢

    • ม׵ϩδοΫ͸গ͠ಠಛ͕ͩɺهࣄ಺Ͱߟ͑ํ͕ஸೡʹઆ໌͞Ε͓ͯΓɺ

    ͳ͓͔ͭʮࠓճͷ࢓༷ͷΈ࢖͑Δํ๏ͩͱׂΓ੾ͬͯߟ͑Δʯͱ

    τϨʔυΦϑ͕͋Δ͜ͱ΋ͪΌΜͱ֮ࣗͰ͖͍ͯΔ

    • ͸Δ͙ͪ͞Μɺ͓ΊͰͱ͏͍͟͝·͢ʂ🎉

    View full-size slide

  35. ग़୊ऀʢ@jnchitoʣͷ໛ൣղ౴

    View full-size slide

  36. ๻͕ॻ͍ͨίʔυ͸͜Μͳײ͡ (1/3)
    class TenjiMaker
    def to_tenji(text)
    tenji_list = text.split(' ').map { |romaji| Tenji.new(romaji) }
    join(tenji_list)
    end
    private
    def join(tenji_list)
    tenji_list
    .map { |tenji| tenji.to_s.split("\n") }
    .transpose
    .map { |row| row.join(' ') }
    .join("\n")
    end
    end

    View full-size slide

  37. ๻͕ॻ͍ͨίʔυ͸͜Μͳײ͡ (2/3)
    class Tenji
    DAN = {
    'A' => 0b100000, 'I' => 0b101000, 'U' => 0b110000,
    'E' => 0b111000, 'O' => 0b011000,
    }
    GYO = {
    'K' => 0b000001, 'S' => 0b000101, 'T' => 0b000110, 'N' => 0b000010,
    'H' => 0b000011, 'M' => 0b000111, 'Y' => 0b010000, 'R' => 0b000100,
    }
    def initialize(romaji)
    @romaji = romaji
    end
    # ͭͮ͘

    View full-size slide

  38. ๻͕ॻ͍ͨίʔυ͸͜Μͳײ͡ (3/3)
    # ͖ͭͮ
    def to_i
    case @romaji.chars
    in ['Y' => gyo, 'A' | 'U' => dan] then GYO[gyo] | (DAN[dan] >> 4)
    in ['Y' => gyo, 'O' => dan] then GYO[gyo] | (DAN[dan] >> 2)
    in ['W', 'A' => dan] then DAN[dan] >> 4
    in [gyo, dan] then GYO[gyo] | DAN[dan]
    in ['N'] then 0b000111
    in [dan] then DAN[dan]
    end
    end
    def to_s
    sprintf('%06b', to_i).tr('01', '-o').scan(/../).join("\n")
    end
    end

    View full-size slide

  39. ίʔυ͸ͪ͜Βʹஔ͍ͯ͋Γ·͢
    • https://github.com/JunichiIto/tenji-maker-challenge-for-ginza-rails/tree/answer

    View full-size slide

  40. ϩδοΫͷղઆ

    View full-size slide

  41. جຊతͳߟ͑ํ
    • TenjiMakerΫϥεͱ͸ผʹTenjiΫϥεΛ࡞Δ

    • TenjiΫϥε͸ɺ͔ͳ1จࣈʹରԠ͢Δ఺ࣈʢͷจࣈྻʣΛੜ੒Ͱ͖Δ

    • ʮ͔ͳ1จࣈˠ఺ࣈʯͷ͘͠Έ͑͞Ͱ͖Ε͹ɺ͋ͱ͸ͦΕΛ࿈݁͢Δ͚ͩ
    Tenji.new('A').to_s
    #=> o-
    # --
    # --
    Tenji.new('HI').to_s
    #=> o-
    # o-
    # oo

    View full-size slide

  42. ఺ࣈΛͲͷΑ͏ʹߏங͢Δ͔ʁ
    • ఺ࣈʹ͸6ͭͷυοτʢ఺ʣ͕͋Δ

    • ֤υοτ͸"o"ͱ"-"ͷ2ͭͷঢ়ଶΛ࣋ͭ

    • "o"ͱ"-"͸ONͱOFFͰ͋Γɺ1ͱ0Ͱදͤ͹ɺ6Ϗοτͷ2ਐ਺ͰදݱͰ͖Δ
    ᶃ ʔ

    ʔ ᶇ

    ʔ ᶈ
    0b100011
    ᶃʔʔʔᶇᶈ
    → →
    1 2 3 4 5 6

    View full-size slide

  43. ఺ࣈΛͲͷΑ͏ʹߏங͢Δ͔ʁ
    • ͨͩ͠ɺϓϩάϥϜͰॲཧ͢Δ৔߹͸ԣॻ͖ͷํ͕Կ͔ͱ౎߹͕ྑ͍

    • ͦ͜Ͱࠓճ͸͋͑ͯυοτͷ൪߸Λԣॻ͖ͰׂΓৼΔ͜ͱʹ͢Δ
    ᶃ ᶆ

    ᶄ ᶇ

    ᶅ ᶈ

    ᶃ ᶄ

    ᶅ ᶆ

    ᶇ ᶈ
    λ

    ς
    Ϥί
    0b110011
    0b101101
    1 2 3 4 5 6
    1 2 3 4 5 6
    λς
    Ϥί

    View full-size slide

  44. ఺ࣈΛͲͷΑ͏ʹߏங͢Δ͔ʁ
    • 2ਐ਺ͷ੔਺஋͸࿦ཧ࿨ (OR) Λ࢖ͬͯɺ2ͭͷ஋Λ߹੒Ͱ͖Δ

    • ʮ͖ʯΛ࡞Δ৔߹
    ᶃ ʔ

    ᶅ ʔ

    ʔ ᶈ
    ͖
    ͍ஈ 0b101000
    ͔ߦ 0b000001
    ͖ɹ 0b101001
    0b101000 | 0b000001 #=> 0b101001
    1 2 3 4 5 6

    View full-size slide

  45. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ฼ԻΛҰ൪Լ·ͰԼΖ͢ඞཁ͕͋ΔɻͲ͏͢Ε͹͍͍͔ʁ
    ʔ ᶄ

    ʔ ʔ

    ᶇ ʔ
    ʔ ᶄ

    ʔ ʔ

    ᶇ ᶈ
    ʔ ᶄ

    ʔ ᶆ

    ᶇ ʔ
    ΍ɹɹɹɹɹΏɹɹɹɹɹΑ

    View full-size slide

  46. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ӈϏοτγϑτ͕࢖͑ͦ͏
    ᶃ ᶄ

    ʔ ʔ

    ʔ ʔ
    0b110000

    View full-size slide

  47. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ӈϏοτγϑτ͕࢖͑ͦ͏
    ʔ ᶄ

    ᶅ ʔ

    ʔ ʔ
    0b110000 >> 1

    0b011000

    View full-size slide

  48. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ӈϏοτγϑτ͕࢖͑ͦ͏
    ʔ ʔ

    ᶅ ᶆ

    ʔ ʔ
    0b110000 >> 2

    0b001100
    2ͭӈʹϏοτγϑτ

    ͢Ε͹1ஈԼ͕Δ

    View full-size slide

  49. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ӈϏοτγϑτ͕࢖͑ͦ͏
    ʔ ʔ

    ʔ ᶆ

    ᶇ ʔ
    0b110000 >> 3

    0b000110

    View full-size slide

  50. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ӈϏοτγϑτ͕࢖͑ͦ͏
    ʔ ʔ

    ʔ ʔ

    ᶇ ᶈ
    0b110000 >> 4

    0b000011 4ͭӈʹϏοτγϑτ

    ͢Ε͹2ஈԼ͕Δ

    View full-size slide

  51. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ӈϏοτγϑτͨ͠஋ʹ࿦ཧ࿨Ͱʮ΍ߦʯΛද͢ᶄͷυοτΛ߹੒͢Ε͹OK
    (0b011000 >> 2) | 0b010000
    #=> 0b010110
    ʔ ᶄ

    ᶅ ʔ

    ʔ ʔ
    ʔ ʔ

    ʔ ᶆ

    ᶇ ʔ

    ͓
    (0b110000 >> 4) | 0b010000
    #=> 0b010011
    ᶃ ᶄ

    ʔ ʔ

    ʔ ʔ
    ʔ ʔ

    ʔ ʔ

    ᶇ ᶈ

    ͏

    View full-size slide

  52. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ӈϏοτγϑτͨ͠஋ʹ࿦ཧ࿨Ͱʮ΍ߦʯΛද͢ᶄͷυοτΛ߹੒͢Ε͹OK
    (0b011000 >> 2) | 0b010000
    #=> 0b010110
    ʔ ᶄ

    ᶅ ʔ

    ʔ ʔ
    ʔ ᶄ

    ʔ ᶆ

    ᶇ ʔ

    ͓ Α
    (0b110000 >> 4) | 0b010000
    #=> 0b010011
    ᶃ ᶄ

    ʔ ʔ

    ʔ ʔ
    ʔ ᶄ

    ʔ ʔ

    ᶇ ᶈ

    ͏ Ώ

    View full-size slide

  53. ʮΘʯ͸Ͳ͏͢Δʁ
    • ʮ͋ʯΛҰ൪Լ·ͰԼΖ͢ ʹ 4ͭӈʹϏοτγϑτ͢Δ
    ᶃ ʔ

    ʔ ʔ

    ʔ ʔ
    ʔ ʔ

    ʔ ʔ

    ᶇ ʔ

    0b100000 >> 4 #=> 0b000010
    ͋ Θ

    View full-size slide

  54. ʮΜʯ͸Ͳ͏͢Δʁ
    • Ͳͷϧʔϧʹ΋౰ͯ͸·Βͳ͍ͷͰɺͨͩͷݻఆ஋ͱݟͳ͢
    ʔ ʔ

    ʔ ᶆ

    ᶇ ᶈ
    0b000111
    ʔʔʔᶆᶇᶈ
    → →
    Μ

    View full-size slide

  55. ஈͱߦͷϚοϐϯάදʢϋογϡʣΛ࡞Δ
    • ฼ԻʢஈʣͱࢠԻʢߦʣͷରԠؔ܎ΛϋογϡͰ·ͱΊΔ

    • ʮΜʯ͸ͨͩͷݻఆ஋ͳͷͰɺ͜ͷϋογϡʹ͸ؚΊͳ͍
    class Tenji
    DAN = {
    'A' => 0b100000, 'I' => 0b101000, 'U' => 0b110000,
    'E' => 0b111000, 'O' => 0b011000,
    }
    GYO = {
    'K' => 0b000001, 'S' => 0b000101, 'T' => 0b000110, 'N' => 0b000010,
    'H' => 0b000011, 'M' => 0b000111, 'Y' => 0b010000, 'R' => 0b000100,
    }

    View full-size slide

  56. ϩʔϚࣈΛͲ͏΍ͬͯߦͱஈʹ෼͚Δ͔ʁ
    • charsϝιουͰϩʔϚࣈ͸ஈͱߦʹ෼ղ͢Δ

    • Ϛοϐϯάද͔Β਺஋Λऔಘ͠࿦ཧ࿨Λฦ͢ / ʮ͍͋͏͓͑ʯ͸ஈ͚ͩฦ͢
    # gyo="K", dan="I" ͕୅ೖ͞ΕΔ


    gyo, dan = "KI".chars
    # GYO["K"]=0b000001, DAN["I"]=0b101000 Ͱ࿦ཧ࿨͸ 0b101001
    GYO[gyo] | DAN[dan]
    # dan="A" ͕୅ೖ͞ΕΔ


    dan, = "A".chars
    # DAN["A"]=0b100000
    DAN[dan]

    View full-size slide

  57. 2จࣈͱ1จࣈͷͱ͖ͰͲ͏৚݅෼ذ͢Δʁ
    • ύλʔϯϚονʢcase/inࣜʣΛ࢖ͬͯ഑ྻͷߏ଄ʹண໨͢Δͱศརͦ͏
    def to_i
    case @romaji.chars
    in [gyo, dan]
    GYO[gyo] | DAN[dan]
    in [dan]
    DAN[dan]
    end
    end
    charsͷ໭Γ஋͕["K", "I"]ͳΒ͜͜ʹϚον
    ͞Βʹɺม਺gyoʹ"K"͕ɺม਺danʹ"I"͕
    ͦΕͧΕ୅ೖ͞ΕΔ

    View full-size slide

  58. 2จࣈͱ1จࣈͷͱ͖ͰͲ͏৚݅෼ذ͢Δʁ
    • ύλʔϯϚονʢcase/inࣜʣΛ࢖ͬͯ഑ྻͷߏ଄ʹண໨͢Δͱศརͦ͏
    def to_i
    case @romaji.chars
    in [gyo, dan]
    GYO[gyo] | DAN[dan]
    in [dan]
    DAN[dan]
    end
    end
    charsͷ໭Γ஋͕["A"]ͳΒ͜͜ʹϚον
    ͞Βʹɺม਺danʹ"A"͕୅ೖ͞ΕΔ

    View full-size slide

  59. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ͜Ε΋ύλʔϯϚονͰରԠՄೳ
    def to_i
    case @romaji.chars
    in ['Y' => gyo, 'A' | 'U' => dan]
    GYO[gyo] | (DAN[dan] >> 4)
    in ['Y' => gyo, 'O' => dan]
    GYO[gyo] | (DAN[dan] >> 2)
    in [gyo, dan]
    # ҎԼུ
    ["Y", "A"] ͔ ["Y", "U"] ͳΒϚον
    gyo ʹ͸ "Y" ͕
    dan ʹ͸ "A" ͔ "U" ͕
    ͦΕͧΕ୅ೖ͞ΕΔ

    View full-size slide

  60. ʮ΍ΏΑʯ͸Ͳ͏͢Δʁ
    • ͜Ε΋ύλʔϯϚονͰରԠՄೳ
    def to_i
    case @romaji.chars
    in ['Y' => gyo, 'A' | 'U' => dan]
    GYO[gyo] | (DAN[dan] >> 4)
    in ['Y' => gyo, 'O' => dan]
    GYO[gyo] | (DAN[dan] >> 2)
    in [gyo, dan]
    # ҎԼུ
    ["Y","O"] ͳΒϚον
    gyo ʹ͸ "Y" ͕
    dan ʹ͸ "O" ͕
    ͦΕͧΕ୅ೖ͞ΕΔ

    View full-size slide

  61. ʮΘʯ͸Ͳ͏͢Δʁ
    • ͜Ε΋ύλʔϯϚονͰରԠՄೳ
    def to_i
    case @romaji.chars
    # লུ


    in ['W', 'A' => dan]
    DAN[dan] >> 4
    in [gyo, dan]
    # ҎԼུ
    ["W","A"] ͳΒϚον
    dan ʹ͸ "A" ͕୅ೖ͞ΕΔ

    View full-size slide

  62. ʮΜʯ͸Ͳ͏͢Δʁ
    • ͜Ε΋ύλʔϯϚονͰରԠՄೳ
    def to_i
    case @romaji.chars
    # লུ


    in ['N']
    0b000111
    in [dan]
    DAN[dan]
    end
    end
    ["N"] ͳΒϚον
    ม਺͸࢖Θͣݻఆ஋Λฦ͢

    View full-size slide

  63. શ෦·ͱΊΔͱɺ͜͏
    • εϖʔεͷ౎߹্ɺthenͰߦ਺Λઅ໿͠·ͨ͠
    def to_i
    case @romaji.chars
    in ['Y' => gyo, 'A' | 'U' => dan] then GYO[gyo] | (DAN[dan] >> 4)
    in ['Y' => gyo, 'O' => dan] then GYO[gyo] | (DAN[dan] >> 2)
    in ['W', 'A' => dan] then DAN[dan] >> 4
    in [gyo, dan] then GYO[gyo] | DAN[dan]
    in ['N'] then 0b000111
    in [dan] then DAN[dan]
    end
    end

    View full-size slide

  64. ͜ΕͰϩʔϚࣈΛ2ਐ਺ʹม׵Ͱ͖Δʂ
    • to_i ϝιουͷڍಈ͸͜Μͳײ͡
    Tenji.new('KI').to_i #=> 0b101001
    Tenji.new('A').to_i #=> 0b100000
    Tenji.new('YU').to_i #=> 0b010011
    Tenji.new('WA').to_i #=> 0b000010
    Tenji.new('N').to_i #=> 0b000111

    View full-size slide

  65. 2ਐ਺Λ఺ࣈͷจࣈྻʹม׵͢Δ
    • ͋ͱ͸ػցతʹม׵͢Δ͚ͩ
    # to_i ͕ 0b101001 Λฦ͢৔߹


    def to_s
    sprintf('%06b', to_i)
    .tr('01', '-o')
    .scan(/../)
    .join("\n")
    end

    View full-size slide

  66. 2ਐ਺Λ఺ࣈͷจࣈྻʹม׵͢Δ
    • ͋ͱ͸ػցతʹม׵͢Δ͚ͩ
    # to_i ͕ 0b101001 Λฦ͢৔߹


    def to_s
    sprintf('%06b', to_i)
    .tr('01', '-o')
    .scan(/../)
    .join("\n")
    end
    จࣈྻ "101001" ʹม׵

    View full-size slide

  67. 2ਐ਺Λ఺ࣈͷจࣈྻʹม׵͢Δ
    • ͋ͱ͸ػցతʹม׵͢Δ͚ͩ
    # to_i ͕ 0b101001 Λฦ͢৔߹


    def to_s
    sprintf('%06b', to_i)
    .tr('01', '-o')
    .scan(/../)
    .join("\n")
    end
    "0"Λ"-"ʹɺ"1"Λ"o"ʹม׵
    ͭ·Γɺ "o-o--o" ͕Ͱ͖͕͋Δ

    View full-size slide

  68. 2ਐ਺Λ఺ࣈͷจࣈྻʹม׵͢Δ
    • ͋ͱ͸ػցతʹม׵͢Δ͚ͩ
    # to_i ͕ 0b101001 Λฦ͢৔߹


    def to_s
    sprintf('%06b', to_i)
    .tr('01', '-o')
    .scan(/../)
    .join("\n")
    end
    2จࣈͣͭ഑ྻʹ෼ׂ͢Δ
    ͭ·Γɺ ["o-", "o-", "-o"] ͕Ͱ͖͕͋Δ

    View full-size slide

  69. 2ਐ਺Λ఺ࣈͷจࣈྻʹม׵͢Δ
    • ͋ͱ͸ػցతʹม׵͢Δ͚ͩ
    # to_i ͕ 0b101001 Λฦ͢৔߹


    def to_s
    sprintf('%06b', to_i)
    .tr('01', '-o')
    .scan(/../)
    .join("\n")
    end
    ֤ཁૉΛվߦจࣈͰ࿈݁ →
    ʢ׬੒ʂʣ
    o-
    o-
    -o

    View full-size slide

  70. TenjiΫϥεͷશମ૾ (1/2)
    class Tenji
    DAN = {
    'A' => 0b100000, 'I' => 0b101000, 'U' => 0b110000,
    'E' => 0b111000, 'O' => 0b011000,
    }
    GYO = {
    'K' => 0b000001, 'S' => 0b000101, 'T' => 0b000110, 'N' => 0b000010,
    'H' => 0b000011, 'M' => 0b000111, 'Y' => 0b010000, 'R' => 0b000100,
    }
    def initialize(romaji)
    @romaji = romaji
    end
    # ͭͮ͘

    View full-size slide

  71. TenjiΫϥεͷશମ૾ (2/2)
    # ͖ͭͮ
    def to_i
    case @romaji.chars
    in ['Y' => gyo, 'A' | 'U' => dan] then GYO[gyo] | (DAN[dan] >> 4)
    in ['Y' => gyo, 'O' => dan] then GYO[gyo] | (DAN[dan] >> 2)
    in ['W', 'A' => dan] then DAN[dan] >> 4
    in [gyo, dan] then GYO[gyo] | DAN[dan]
    in ['N'] then 0b000111
    in [dan] then DAN[dan]
    end
    end
    def to_s
    sprintf('%06b', to_i).tr('01', '-o').scan(/../).join("\n")
    end
    end

    View full-size slide

  72. TenjiMakerΫϥεͷॲཧ΋ඇৗʹػցత
    class TenjiMaker
    def to_tenji(text)
    tenji_list = text.split(' ').map { |romaji| Tenji.new(romaji) }
    join(tenji_list)
    end
    private
    def join(tenji_list)
    tenji_list
    .map { |tenji| tenji.to_s.split("\n") }
    .transpose
    .map { |row| row.join(' ') }
    .join("\n")
    end
    end

    View full-size slide

  73. TenjiMakerΫϥεͷॲཧ΋ඇৗʹػցత
    class TenjiMaker
    def to_tenji(text)
    tenji_list = text.split(' ').map { |romaji| Tenji.new(romaji) }
    join(tenji_list)
    end
    private
    def join(tenji_list)
    tenji_list
    .map { |tenji| tenji.to_s.split("\n") }
    .transpose
    .map { |row| row.join(' ') }
    .join("\n")
    end
    end
    ೖྗ஋ΛεϖʔεͰ෼ׂͯ͠
    TenjiΫϥεͷ഑ྻΛ࡞Δ

    View full-size slide

  74. TenjiMakerΫϥεͷॲཧ΋ඇৗʹػցత
    class TenjiMaker
    def to_tenji(text)
    tenji_list = text.split(' ').map { |romaji| Tenji.new(romaji) }
    join(tenji_list)
    end
    private
    def join(tenji_list)
    tenji_list
    .map { |tenji| tenji.to_s.split("\n") }
    .transpose
    .map { |row| row.join(' ') }
    .join("\n")
    end
    end
    ֤఺ࣈΛߦ͝ͱʹ෼ׂͯ͠
    ഑ྻͷঢ়ଶʹ໭͢
    [
    ["o-", "o-", "--"], ͍
    ["oo", "--", "o-"] ͵
    ]
    o- oo
    o- --
    -- o-
    ͍ɹ͵

    View full-size slide

  75. TenjiMakerΫϥεͷॲཧ΋ඇৗʹػցత
    class TenjiMaker
    def to_tenji(text)
    tenji_list = text.split(' ').map { |romaji| Tenji.new(romaji) }
    join(tenji_list)
    end
    private
    def join(tenji_list)
    tenji_list
    .map { |tenji| tenji.to_s.split("\n") }
    .transpose
    .map { |row| row.join(' ') }
    .join("\n")
    end
    end
    ߦྻΛ൓సͤ͞Δ
    [
    ["o-", "oo"],
    ["o-", "--"],
    ["--", "o-"]
    ]
    [
    ["o-", "o-", "--"], ͍
    ["oo", "--", "o-"] ͵
    ]
    ͍ɹɹɹ͵

    View full-size slide

  76. TenjiMakerΫϥεͷॲཧ΋ඇৗʹػցత
    class TenjiMaker
    def to_tenji(text)
    tenji_list = text.split(' ').map { |romaji| Tenji.new(romaji) }
    join(tenji_list)
    end
    private
    def join(tenji_list)
    tenji_list
    .map { |tenji| tenji.to_s.split("\n") }
    .transpose
    .map { |row| row.join(' ') }
    .join("\n")
    end
    end
    ߦ಺ͷ֤ཁૉΛεϖʔεͰ࿈݁͢Δ
    [
    ["o-", "oo"],
    ["o-", "--"],
    ["--", "o-"]
    ]
    ͍ɹɹɹ͵
    [
    "o- oo",
    "o- --",
    "-- o-"
    ]
    ͍ɹ͵

    View full-size slide

  77. TenjiMakerΫϥεͷॲཧ΋ඇৗʹػցత
    class TenjiMaker
    def to_tenji(text)
    tenji_list = text.split(' ').map { |romaji| Tenji.new(romaji) }
    join(tenji_list)
    end
    private
    def join(tenji_list)
    tenji_list
    .map { |tenji| tenji.to_s.split("\n") }
    .transpose
    .map { |row| row.join(' ') }
    .join("\n")
    end
    end
    ֤ߦΛվߦจࣈͰ࿈݁͢Δʢ׬੒ʂʣ
    [
    "o- oo",
    "o- --",
    "-- o-"
    ]
    ͍ɹ͵
    o- oo
    o- --
    -- o-
    ͍ɹ͵

    View full-size slide

  78. ϩδοΫͷ͓͞Β͍

    View full-size slide

  79. ϩδοΫͷ͓͞Β͍
    • ϩʔϚࣈˠ఺ࣈͷม׵ϧʔϧ͸TenjiΫϥεʹΧϓηϧԽͨ͠

    • ఺ࣈ͸6Ϗοτͷ2ਐ਺ͱͯ͠ѻͬͨʢυοτͷ൪߸͸ԣಡΈʹஔ͖׵͑ͨʣ

    • ฼ԻʢஈʣͱࢠԻʢߦʣͷ֤਺஋ΛϏοτԋࢉͷ࿦ཧ࿨Ͱ߹੒ͨ͠

    • ϩʔϚࣈΛ฼ԻͱࢠԻʹ෼ղ͢Δࡍͷ৚݅෼ذΛύλʔϯϚονͰ࣮૷ͨ͠

    • ఺ࣈΛ2ਐ਺ͰදݱͰ͖Ε͹ɺ͋ͱ͸ػցతʹจࣈྻԽ͢Δ͚ͩ

    • RailsͰݴ͑͹2ਐ਺͕Ϟσϧɺ"-o"Ͱදͨ͠จࣈྻ͕viewͷΠϝʔδ
    o-
    o-
    -o
    0b101001

    View full-size slide

  80. ໛ൣղ౴ͷ΢ΠʔΫϙΠϯτʁ🤔
    • ॲཧޮ཰ͷ؍఺Ͱ͍͏ͱϕετͳ࣮૷Ͱ͸ͳ͍

    ‣ TenjiΫϥεͰ࡞ͬͨจࣈྻΛTenjiMakerΫϥε͕࠶෼ղ͍ͯ͠Δ

    ‣ ͕ɺʮૣ͗͢Δ࠷దԽ͸ॾѱͷࠜݯʯͱ͍͏֨ݴ΋͋Δ

    ‣ ࠷దԽ͸࣮ߦ଎౓͕໰୊ʹͳͬͨͱ͖ʹߟ͑Ε͹ྑ͍

    • TenjiΫϥεͷto_i΍to_s͍ͬͯ͏ϝιου໊͸͜ΕͰ͍͍ͷ͔ͳ͋ʁ

    • ʮ΍ΏΑʯ΍ʮΘʯͰϏοτγϑτΛ࢖͏ͷ͸ͪΐͬͱ΍Γ͔͗͢΋ʁ

    View full-size slide

  81. ൃలฤɿਏޱόʔδϣϯ΋͋Γ·͢🌶
    • ࠓճରԠΛݟૹͬͨ఺ࣈʹ΋ରԠ͢Δɺਏޱόʔδϣϯ΋͋Γ·͢

    ‣ ਏޱͷೖྗྫʮͪʔͨʔʯʮͺΜͩʯʮ͖Μ͗ΐʯʮΒͬ͜ʯͳͲ

    • ςετύλʔϯ͸Լهϖʔδʹࡌ͍ͤͯ·͢

    https://gist.github.com/JunichiIto/1c8565bbffd0b5cf589b905f9ad2388f

    • ڵຯ͕͋Δํ͸ͪ͜Βʹ΋νϟϨϯδʂ

    • ͪͳΈʹ๻ͷ໛ൣղ౴ͩͱTenjiΫϥεͷߦ਺͸108ߦͰͨ͠

    https://github.com/JunichiIto/tenji-maker-challenge-for-ginza-rails/blob/karakuchi-answer/lib/tenji.rb

    View full-size slide

  82. ϏοτԋࢉʁύλʔϯϚονʁʁ


    ͦ΋ͦ΋Α͘Θ͔ͬͯͳ͍͔΋…

    View full-size slide

  83. ϓϩΛ໨ࢦ͢ਓͷͨΊͷ3VCZೖ໳ [վగ2൛]

    ҏ౻ ३Ұ ஶ

    ൃച೔ 2021೥12݄2೔

    ٕज़ධ࿦ࣾ / 3,278ԁʢ੫ࠐʣ
    ͦΜͳ͋ͳͨʹʂ
    • վగ2൛Ͱ͸Ruby 3.0ʹϑϧରԠ

    • Ϗοτԋࢉ΋ύλʔϯϚον΋શ෦
    ࡌͬͯ·͢

    • ಛʹύλʔϯϚονͷઆ໌ʹؔͯ͠͸
    ੈքτοϓϨϕϧʂʁ

    View full-size slide

  84. Rubyίϛολ⁋ຊ͞ΜʹΑΔਪનͷݴ༿
    https://twitter.com/k_tsj/status/1469535631995191303

    View full-size slide

  85. ஸೡͳઆ໌ͱ๛෋ͳαϯϓϧίʔυ

    View full-size slide

  86. FAQ
    Q. ͯ͞͸͓લɺຊͷએ఻Λ͢ΔͨΊʹ͜ͷ໰୊Λ࡞ͬͨͳʁ

    A.

    ͍͍͑͑ʂ

    ύλʔϯϚονΛ࢖͓͏ͱࢥͬͨͷ͸໰୊Λ࡞ͬͨޙͰ͢ʂʂʢ΄Μͱʹʣ

    View full-size slide

  87. About me
    • ҏ౻ ३Ұ

    • ιχοΫΨʔσϯͷRailsϓϩάϥϚ

    • ϑΟϤϧυϒʔτΩϟϯϓͷϝϯλʔ

    • QiitaϥϯΩϯά1Ґʢ2022೥1݄ݱࡏʣ

    • Twitter @jnchito

    • Blog https://blog.jnito.com/

    View full-size slide

  88. ฐࣾڠࢍͷϋοΧιϯΠϕϯτ͕͋Γ·͢ʂ
    https://tsukuaso.connpass.com/event/234370/
    • 2022.2.17ʙ25։࠵ɺࢀՃඅແྉ

    • ߽՚ͳ෭৆Λ༻ҙ͍ͯ͠·͢🎁

    • Կ͔࡞Δ͜ͱ͕େ޷͖ͳํ͸ʮୈ2ճ πΫͬͯΞιͿϋοΧιϯʯ΁ʂ

    View full-size slide

  89. Everyday Rails RSpecʹΑΔRailsςετೖ໳

    Aaron Sumner ஶɺҏ౻ ३Ұ ༁

    ൢചՁ֨ 19.00 USD ࠓ͚ͩ16.99 USD
    Ξοϓσʔτ͠·ͨ͠ʂ
    • αϯϓϧΞϓϦΛRails 7.0Խ

    • ࠷৽ͷRSpec΍gemʹରԠ

    • ظؒݶఆͰ 16.99υϧͰൢചத

    • RSpecΛϚελʔ͍ͨ͠ํ͸ͥͻʂ
    https://leanpub.com/everydayrailsrspec-jp/

    View full-size slide

  90. ຊ೔ͷ·ͱΊ

    View full-size slide

  91. ͜ͷߨԋͰֶΜͰ΄͍͜͠ͱʢ࠶ܝʣ
    • ࣗ෼͕ॻ͍ͨίʔυͱଞͷਓ͕ॻ͍ͨίʔυΛݟൺ΂ͯΈΑ͏

    • ͍ΖΜͳϩδοΫͷߟ͑ํΛֶ΅͏

    • Rubyͷݴޠػೳ΍ศརͳϝιουʹֶ͍ͭͯ΅͏

    • ͜͜ͰֶΜͩ಺༰Λ໌೔͔Βॻࣗ͘෼ͷίʔυʹ׆͔ͯ͠ΈΑ͏

    • Կ͔ͻͱͭͰ΋໾ཱͭ৘ใ͕͋Ε͹޾͍Ͱ͢😊

    View full-size slide

  92. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠
    Ξϯέʔτͷճ౴΋͓଴͍ͪͯ͠·͢ʂ

    View full-size slide