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

The Better RuboCop World to enjoy Ruby

Yasuko Ohba
September 10, 2022
12k

The Better RuboCop World to enjoy Ruby

The slide of my talk in RubyKaigi 2022.

https://rubykaigi.org/2022/presentations/nay3.html#day3

Yasuko Ohba

September 10, 2022
Tweet

Transcript

  1. Yasuko Ohba (@nay3) • Started programing in 1987 • Ruby

    (mostly Rails) user since 2006 • One of founders of Everyleaf Corporation (גࣜձࣾສ༿) in Japan • Recently came back to software development works • A RuboCop user
  2. In this talk I will talk about the problems that

    can arise in the development team using RuboCop and how to solve them RuboCopʢͷΑ͏ͳπʔϧʣΛ࢖͏͜ͱͰ
 ։ൃνʔϜʹى͜ΓಘΔ໰୊ͱ
 ͦͷղܾํ๏ʹ͍ͭͯ࿩͠·͢
  3. Thanks to RuboCop !! • I like and appreciate RuboCop


    ɹRuboCopʹ͸େม͓ੈ࿩ʹͳ͓ͬͯΓײँ͍ͯ͠·͢ • I don’t intend to criticize RuboCop
 ɹRuboCopΛdisΔҙਤ͸͋Γ·ͤΜ
  4. What I want to say Is there anything we can

    do to make RuboCop 
 (and similar tools) better and safer ?
 
 ΑΓྑ҆͘શʹRuboCopΛར༻Ͱ͖ΔΑ͏ʹɺ
 ͳʹ͔Ͱ͖Δ͜ͱ͸ͳ͍͔ʁ
  5. Let me ask you questions 1. Have you used RuboCop

    ?
 ɹRuboCopΛ࢖ͬͨ͜ͱͷ͋Δํ✋ 2. Do you love RuboCop ?
 ɹRuboCop͕େ޷͖ͳํ✋ 3. Have you felt uncomfortable with RuboCop ?
 ɹRuboCopʹۤखײΛײͨ͜͡ͱͷ͋Δํ✋ 4. Have you written .rubocop.yml by yourself ?
 ɹRuboCopͷઃఆϑΝΠϧʢ.rubocop.ymlʣΛ࡞ΓࠐΜͩ͜ͱͷ͋Δํ✋
  6. • It checks your code and extract the problems
 ɹίʔυΛνΣοΫ͠ɺ໰୊఺Λநग़ͯ͘͠Ε·͢

    • Also has a function that fi xes problems automatically if possible
 ɹࣗಈͰमਖ਼ͯ͘͠ΕΔػೳ΋͋Γ·͢ https://github.com/rubocop/rubocop
  7. Typical usage in teams • Prevent bad code from being

    committed by pre-commit hook
 ɹpre-commitͰ૸Βͤͯɺ
 ɹҧ൓͕͋Ε͹ίϛοτ͞Εͳ͍Α͏ʹ͢Δ • Prevent bad code from being merged by running RuboCop in CI
 ɹCIͰ૸Βͤͯɺ
 ɹҧ൓͕͋Ε͹Ϛʔδ͞Εͳ͍Α͏ʹ͢Δ
  8. In that case • RuboCop is just like a real

    cop
 ɹܯ׭ͷΑ͏ʹ • It cracks down on codes that don't follow the rules
 ɹϧʔϧʹԊ͍ͬͯͳ͍ίʔυΛݫ͘͠औΓక·Δ
  9. Good point VALUES = [ 'foo'.freeze, 'bar'.freeze ] Style/MutableConstant: Freeze

    mutable objects assigned to constants Layout/FirstArrayElementIndentation: Indent the right bracket the same as the start of the line where the left bracket is. VALUES = [ 'foo'.freeze, 'bar'.freeze ].freeze Very Useful !!
  10. It keeps code clean • Mostly you can automatically correct

    the code with a single command
 ɹίϚϯυҰൃͰमਖ਼Ͱ͖Δ͜ͱ͕ଟ͍ • Teammates are freed from reviewing trivial mistakes
 ɹࠣࡉͳελΠϧҧ൓ʹ͍ͭͯͷϨϏϡʔ͔Βͷղ์ • Only clean code goes into the main branch
 ɹ͖Ε͍ͳίʔυ͚͕ͩmainϒϥϯνʹೖΔ҆৺ײ
  11. Example 1 class UsersController < ApplicationController def show end Style/EmptyMethod:

    Put empty method de fi nitions on a single line. • It's more convenient not to do so in this case
 ɹैΘͳ͍΄͏͕͜ͷ৔߹͸ศར def show; end def show # just render it end
  12. Example 2 • Renaming makes it ambiguas in this case


    ɹ໊લΛม͑Δͱ͔͑ͬͯᐆດʹͳΔ class ParentModel < ApplicationRecord def has_child? … Naming/PredicateName: Rename has_child? to child? def child?
  13. I can introduce a lot, but that is not the

    purpose, so not here ͨ͘͞Μ঺հͰ͖ΔΜ͚ͩͲ ͦΕ͕໨తͰ͸ͳ͍ͷͰׂѪ
  14. It's just that sometimes it doesn't fi t the situation

    ঢ়گʹ߹Θͳ͍͜ͱ͕͋Δͱ͍͏͚ͩ
  15. Let’s imagine how a junior engineer behaves when RuboCop detects

    a violation RuboCopͰҧ൓͕ݕग़͞ΕͨΒɺ δϡχΞΤϯδχΞ͸Ͳ͏͢Δ͔ʁ
  16. Most junior engineers try to follow the rules (Perhaps, particularly

    in Japan) େଟ਺ͷδϡχΞΤϯδχΞ͸ ϧʔϧʹै͓͏ͱ͢Δ (΋͔ͨ͠͠Βɺಛʹ೔ຊͰ͸…)
  17. This simple act to follow the rules can lead to

    tragic waste ϧʔϧʹै͓͏ͱ͢Δ͜ͱ͕ ൵ܶతͳແବʹͭͳ͕ΔڪΕ͕͋Δ
  18. Beginners in the development team are forced to write code

    under the rules that they cannot judge for themselves ։ൃνʔϜ಺ͷॳ৺ऀ͸ɺ ࣗ෼ͰΑ͋͠͠Λ൑அͰ͖ͳ͍ϧʔϧʹ ੍໿͞Εͳ͕ΒίʔυΛॻ͘͜ͱʹͳΔ
  19. Ultimately, for beginners under RuboCop, RuboCop's allowed writing style ==

    Ruby ۃ࿦͢ΔͱɺRuboCopΛ࢖͍ͬͯΔ νʔϜ಺ͷॳ৺ऀʹͱͬͯ͸ɺ RuboCopͰڐ͞Εͨॻ͖ํ == Ruby
  20. The Ruby language gives programmers a lot of freedom, but

    that freedom doesn't always reach beginners when using Ruby via RuboCop Rubyͷ༩͑ͯ͘ΕΔେ͖ͳࣗ༝͸ RuboCopӽ͠ʹRubyΛ࢖͏ͱ͖ ඞͣ͠΋ॳ৺ऀʹ͸ಧ͔ͳ͍
  21. I think we should question “Is it still true for

    beginners under RuboCop?” ʮRuboCopΛ࢖ͬͯRubyΛॻ͍͍ͯΔॳ৺ऀ ʹ΋ͦ͏ࢥͬͯ΋Β͑Δ͔Ͳ͏͔ʯ ͱ͍͏໰͍͔͚Λͨ͠΄͏͕͍͍ͷͰ͸ͳ͍͔
  22. Under RuboCop, unskilled people might be trapped while skilled people

    are enjoying Ruby freely εΩϧͷ͋Δਓ͸ RuboCopΛ࢖͍ͬͯͯ΋ RubyΛࣗ༝ʹָ͠ΊΔ͕ɺ εΩϧͷͳ͍ਓ͸RuboCopʹڧ੍͘໿͞ΕΔ
  23. It's annoying to have a rule that doesn't fi t

    your situation and get stuck frequently ঢ়گʹ߹Θͳ͍ϧʔϧʹ සൟʹҾ͔͔ͬΔͷ͸൥Θ͍͠
  24. Even after deciding that the rules don't fi t the

    situation, something needs to be done ϧʔϧ͕ঢ়گʹ߹Θͳ͍ͱ ൑அͰ͖ͨ৔߹Ͱ΋ɺ ͳʹ͔ͷରॲ͕ඞཁʹͳΔ
  25. Strategies 1. Change the rule for the project
 ɹϓϩδΣΫτશମͷϧʔϧΛม͑Δ 2.

    Change the rule in that code
 ɹͦͷίʔυͰ͸ϧʔϧΛม͑Δ 3. Just follow the rule
 ɹͱΓ·ɺϧʔϧʹै͓ͬͯ͘
  26. Few engineers can take Strategy 1 ઓུ1ΛͱΕΔΤϯδχΞ͸ গ਺ʹײ͡ΒΕΔ 1. Change

    the rule for the project 
 ɹϓϩδΣΫτશମͷϧʔϧΛม͑Δ
  27. Dif fi culty of Strategy 1 • “I can't tell

    if that's the case in other situations as well.”
 ɹʮ΄͔ͷέʔεͰ΋ঢ়گʹ߹Θͳ͍͔·Ͱ͸
 ɹ൑அͰ͖ͳ͍ʯ • “It's hard to convince the whole team”
 ɹʮνʔϜશһΛઆಘ͢Δͷ͸େมͦ͏ͩʯ 1. Change the rule for the project 
 ɹϓϩδΣΫτશମͷϧʔϧΛม͑Δ
  28. Taking easier strategies • This may not solve the problem

    conclusively
 ɹ໰୊ͷ࠷ऴղܾʹͭͳ͕Βͣɺ
 ɹ·ͨ͜ͷίετΛ෷͏ඞཁ͕ൃੜ͢Δ͔΋͠Εͳ͍ 2. Change the rule in that code
 ɹͦͷίʔυͰ͸ϧʔϧΛม͑Δ 3. Just follow the rule
 ɹͱΓ·ɺϧʔϧʹै͓ͬͯ͘
  29. In short "Rules that do not fi t the situation”

    create disadvantages ʮঢ়گʹ߹Θͳ͍ϧʔϧʯ͸ σϝϦοτΛੜΈग़͢
  30. Disadvantages • Decrease in development speed and productivity
 ɹ։ൃ଎౓ɾੜ࢈ੑͷ௿Լ •

    Code might get worse to avoid violation
 ɹRuboCopͷҧ൓Λආ͚ΔͨΊʹ
 ɹίʔυ͕վѱ͞ΕΔϦεΫ
  31. Why don't you just set it up to fi t

    the situation? ঢ়گʹ߹͏Α͏ʹઃఆͨ͠Β ͍͍Μ͡ΌΜʁ
  32. RuboCop is fl exible (1) All rules can be disabled

    or customized from the default ͢΂ͯͷϧʔϧ͸ɺແޮʹͨ͠ΓɺσϑΥϧτͱ͸ҟͳΔ ํ਑ʹมߋ͢Δ͜ͱ͕Ͱ͖·͢
  33. RuboCop is fl exible (2) • You can ignore certain

    rules in a certain code
 ಛఆͷίʔυͰಛఆͷϧʔϧΛແࢹ͢Δ͜ͱΛ
 એݴͰ͖·͢
  34. RuboCop’s Philosophy “Whatever style preferences you have RuboCop is there

    for you. That's our promises and our guarantee.” https://docs.rubocop.org/rubocop/index.html#philosophy
  35. "Style Guide" • Ruby is a dynamic language
 Ruby͸ಈతͳݴޠ •

    The good thing about Ruby is that you can write in the best way for your situation
 ঢ়گʹ͋Θͤͯ࠷దͳॻ͖ํ͕Ͱ͖Δͷ͕Rubyͷ͍͍ͱ͜Ζ • In my opinion, the style guide in “Ruby Way” should be dynamic
 RubyͬΆ͍ελΠϧΨΠυ͸ɺಈతͳͷͰ͸ͳ͍͔ʁ
  36. Well, you have the right not to use RuboCop I

    want to use RuboCop because it is useful, and it is already kind of standard
 RuboCop͸ศརͳͷͰ࢖͍͍ͨ͠ɺ΋͸΍ඪ४త
  37. Point is • The need to use RuboCop is growing


    ɹRuboCopΛ࢖͏ඞཁੑ͸ڧ͘ͳ͍ͬͯΔ • My concern is not about “(static) style guide preferences"
 ʮͲͷ(੩తͳ) Style GuideΛ޷Ή͔ʯͰ͸ࡁ·ͳ͍࿩ͩͱࢥ͍ͬͯΔ • People may be forced to follow rules that do not fi t their situation
 ɹঢ়گʹ߹Θͳ͍ϧʔϧΛڧ੍͞ΕΔϦεΫ͕͋Δ • Con fi guration fl exibility is not enough to avoid the risk
 ɹઃఆͷॊೈ͚ͩ͞Ͱ͸ͦͷϦεΫΛճආͰ͖ͳ͍
  38. Con fi guration fl exibility is not enough to avoid

    the risk ઃఆͷॊೈ͚ͩ͞Ͱ͸ͦͷϦεΫΛճආͰ͖ͳ͍
  39. You need to judge the validity of the rule in

    order to set up ͏·͘ઃఆ͢ΔͨΊʹ͸ ϧʔϧͷଥ౰ੑΛ൑அͰ͖Δඞཁ͕͋Δ
  40. You need to think about whether problems will occur in

    all the code written in the future, not on the correctness at fi rst glance Ұݟͯ͠ͷਖ਼͠͞Ͱ͸ͳ͘ɺ
 ະདྷʹॻ͔ΕΔίʔυ΋ؚΊͯ
 ໰୊͕ى͖ͳ͍͔ߟ͑Δඞཁ͕͋Δ
  41. You need technical ability and experience to judge the validity

    looking to the future কདྷΛݟ௨ͯ͠ ͋Δϧʔϧ͕Ͳͷ͘Β͍ద੾͔Λ ൑அ͢Δʹ͸ٕज़ྗͱܦݧ͕ඞཁ
  42. Even the RuboCop team would not be able to foresee

    the future needs of every project in the world RuboCopνʔϜ΋ ͋ΒΏΔνʔϜͷະདྷͷχʔζΛ ༧૝͸Ͱ͖ͳ͍
  43. The surest way to avoid such disadvantages is to con

    fi gure the rules well for your team by yourself ໰୊Λ๷͙΋ͬͱ΋࣮֬ͳํ๏͸ɺ ࣗ෼ͨͪͷͨΊͷϧʔϧΛ ࣗ෼ࣗ਎Ͱ͏·͘ઃఆ͢Δ͜ͱ
  44. In my case • I’ve created a rule template of

    the baseline for our company
 ɹࣗࣾ޲͚ͷϕʔεϥΠϯͷϧʔϧͷ਽ܗΛ࡞ͬͨ • WIP
  45. I would like to introduce the details of that work,

    but I don't have time today ϧʔϧͮ͘Γͷৄࡉʹ͍ͭͯ΋͓࿩͍ͨ͠ Ͱ͕͢ࠓ೔͸͕࣌ؒͳͦ͞͏
  46. Main evaluation viewpoints ओͳධՁ؍఺ 1. Risk that code will get

    worse
 ɹίʔυ͕վѱ͞ΕΔϦεΫ 2. Avoid opposite values
 ɹਅٯͷՁ஋؍ 3. Protect freedom of expression
 ɹදݱͷࣗ༝ΛकΔ 4. Don't discourage DSL
 ɹDSLԽʹྫྷਫΛ͔͚ͳ͍ I will write the rest part in our ‘ສ༿note' ଓ͖͸ສ༿noteʹͰ΋ ॻ͍͍͖͍ͯͨͱࢥ͍·͢
  47. It’s too hard !! • Imagine if there is a

    right reason to want to break the rule
 ɹϧʔϧʹҧ൓͍ͨ͠ਖ਼౰ͳཧ༝Λ૝૾ • Consider the frequency of that cases
 ɹҧ൓ͨ͘͠ͳΔέʔεͷස౓Λݕ౼ • Compare the advantages and disadvantages of adopting the rule
 ɹϧʔϧΛద༻͢ΔϝϦοτͱσϝϦοτΛൺֱ • Continue to make judgments as new rules coming
 ɹࠓޙ΋৽͍͠ϧʔϧ͕௥Ճ͞ΕΔͨͼʹܧଓతʹબผ࡞ۀ
  48. RuboCop seems to take the view that there is a

    concept of 'style' on the surface of the code, and it can be statically determined to be correct or not RuboCop͸ɺίʔυͷද૚ʹελΠϧͱ͍͏֓೦͕ ͋ΓɺԿ͕ྑ͍ελΠϧ͔͸ৗʹ੩తʹܾΊΒΕΔͱ ͍͏෺ͷݟํΛ͍ͯ͠ΔΑ͏ʹײ͡Δ
  49. Part of this view fi ts to Ruby, and part

    does not ͜ͷ෺ͷݟํ͸ Rubyʹ౰ͯ͸·Δ෦෼ͱ ౰ͯ͸·Βͳ͍෦෼͕͋Δ
  50. Poem The code expression that RuboCop treats as style is

    sometimes not the style but the heart RuboCop͕ελΠϧͱͯ͠ ѻ͍ͬͯΔίʔυ্ͷදݱ͸ɺ ࣌ʹɺελΠϧͰ͸ͳ͘৺Ͱ͋Δ
  51. Values that RuboCop expects to be static can be changed

    fl exibly depending on the situation RuboCop͕੩తʹܾΊΒΕΔ ૝ఆͱ͍ͯ͠ΔʮՁ஋؍ʯ͸ɺ ঢ়گ࣍ୈͰॊೈʹมΘΔ΋ͷ
  52. The more willingly you detect points that could be improved,

    the more "rules that don't fi t the situation" you get վળͰ͖Δ͔΋͠Εͳ͍ϙΠϯτΛ ҙཉతʹݕग़͢Δ΄Ͳ ʮঢ়گʹ߹Θͳ͍ϧʔϧʯ͕ଟ͘ͳΔ
  53. The solution of this dilemma is left to your .rubocop.yml

    ͜ͷδϨϯϚͷղܾ͕ ͦΕͧΕͷ .rubocop.yml ʹ ҕͶΒΕ͍ͯΔ
  54. Painful things 1. Hardness to tune .rubocop.yml
 ɹઃఆ͕େม 2. Suffering

    from the "rules that do not match the situation" without tuning
 ɹઃఆ͠ͳ͚Ε͹ʮঢ়گʹ߹Θͳ͍ϧʔϧʯ໰୊͕ൃੜ 3. Reducing damages also reduces the opportunities
 ɹڧ੍ʹΑΔμϝʔδΛ࠷খԽ͢Δͱɺ
 ɹίʔυվળͷػձ΋ݮͬͯ͠·͏
  55. Let's divide the usage of RuboCop into two levels 


    RuboCopͷ࢖͍ํΛ ̎ͭͷܥ౷ʹ෼͚ͨΒྑͦ͞͏ʁ 1. Enforcement Levelɹڧ੍Ϩϕϧ 2. Information LevelɹࢀߟϨϕϧ
  56. 2 con fi g fi les • .rubocop-e.yml - for

    Enforcement Level • .rubocop-i.yml - for Information Level
 
 ※names are examples
 ɹɹ໊લ͸ҰྫͰ͢
  57. .rubocop-e.yml Include rules that can be enforced in almost all

    situations
 
 ɹڧ੍ͯ͠΋ɺ΄΅100%ͷঢ়گͰ
 ɹ໰୊͕ͳ͍Α͏ͳϧʔϧΛೖΕΔ
  58. How to use Enforcement Level ڧ੍Ϩϕϧͷ࢖͍ํ Guard your code base

    by using pre-commit hook or CI
 ɹ
 ɹݱঢ়Ͳ͓ΓɺCIͳͲͰΨʔυ͢Δ
  59. How to use Information Level ࢀߟϨϕϧͷ࢖͍ํ • Regularly run in

    CI etc
 ɹCIͳͲͰఆظ࣮ߦ • Informative level violations should be labeled as "informative" not “violations"
 ɹࢀߟϨϕϧͰͷҧ൓͸
 ɹʮҧ൓ʯͰ͸ͳ͘ʮࢀߟ৘ใʯͱͯ͠දࣔ͢Δ
  60. Otherwise we'll fall into the trap of "rules that don't

    fi t the situation" ʮҧ൓ʯͱͯ͠ݟ͑Δͱ ʮঢ়گʹ߹Θͳ͍ϧʔϧʯͷ᠘ʹ ϋϚͬͯ͠·͏
  61. Painful things 1. Hardness to tune .rubocop.yml
 ɹઃఆ͕େม 2. Suffering

    from the "rules that do not match the situation" without tuning
 ɹઃఆ͠ͳ͚Ε͹ʮঢ়گʹ߹Θͳ͍ϧʔϧʯ໰୊͕ൃੜ 3. Reducing damages also reduces the opportunities
 ɹڧ੍ʹΑΔμϝʔδΛ࠷খԽ͢Δͱɺ
 ɹίʔυվળͷػձ΋ݮͬͯ͠·͏
  62. • The reason why it is dif fi cult to

    use other people's settings is that there are a wide range of options for how to compromise ideals and reality.
 ɹଞਓͷઃఆͷ׆༻͕೉͍͠ҰҼ͸ɺ
 ɹཧ૝ͱݱ࣮ͷંΓ߹͍ͷ෇͚ํ͕෯޿͍͔Β • Splitting the levels into lower and upper limits increases the chances of a match
 ɹൣғͷ্ݶɾԼݶΛ෼͚Ε͹ɺҰக͠΍͘͢ͳΔ • Easier and safer to borrow
 ɹ҆৺ͯ͠ഈआͰ͖Δ 1.Hardness to tune .rubocop.yml
 ɹઃఆ͕େม
  63. Maybe we can create typical enforcing level setting examples
 for

    each use case
 (For Rails, for Matz, etc) ༻్ผͷڧ੍Ϩϕϧͷ ઃఆྫΛ࡞ΕΔͱࢥ͏
 ʢRails޲͚ͱ͔ɺMatz޲͚ͱ͔ʣ
  64. If a good "enforcement level setting" can be obtained at

    a low cost, it will be solved
 
 ྑ͍ʮڧ੍Ϩϕϧͷઃఆʯ͕௿ίετͰೖखͰ͖Ε͹ɺ
 ղܾʂʂʂ 2. Suffering from the "rules that do not match the situation" without tuning
 ɹઃఆ͠ͳ͚Ε͹ʮঢ়گʹ߹Θͳ͍ϧʔϧʯ໰୊͕ൃੜ
  65. It makes you feel much less guilty to think “the

    rule is for reference” than “the violation won't have to be fi xed” ʮͦͷϧʔϧ͸ࢀߟ༻ʹ͠Α͏ʯͷ΄͏͕
 ʮҧ൓Λ௚͞ͳ͍͍ͯ͘͜ͱʹ͠Α͏ʯΑΓ
 ͣͬͱࡑѱײ͕গͳ͍
  66. This leads to creating a culture 
 that can counteract

    
 the "rules that don't fi t the situation" trap ʮঢ়گʹ߹Θͳ͍ϧʔϧʯͷ᠘ʹ ର߅Ͱ͖ΔจԽΛ࡞Δ͜ͱ͕Ͱ͖Δ
  67. We can have a nice information level
 code improvement suggestion

    system ࢀߟϨϕϧͷνΣοΫʹجͮ͘
 ૉఢͳίʔυվળఏҊγεςϜΛ
 ར༻Ͱ͖Δͱ͍͍ͳ…ʢເʣ 3. Reducing damages also reduces the opportunities
 ɹڧ੍ʹΑΔμϝʔδΛ࠷খԽ͢Δͱɺ
 ɹίʔυվળͷػձ΋ݮͬͯ͠·͏
  68. There is a gradation in the validity ( fi rmness)

    of rules ϧʔϧͷଥ౰ੑʢݻ͞ʣʹ͸άϥσʔγϣϯ͕͋Δ Fits 100% Fits 80%
 ɹex. Not suitable if expressibility is 
 more important than consistency for you Fits 90%
 ɹex. Not suitable for DSLs Unstable Firm rules
  69. Make it easier to handle areas that cannot be determined

    by 0/1 0/1Ͱ൑ఆͰ͖ͳ͍ྖҬΛѻ͍΍͘͢ (00% #"% .":#&(00% )VNBOTDBOBMTPSFWJFXBOEKVEHF Enforcement Information
  70. One Saturday morning,
 I was working on .rubocop.yml for our

    company ͋Δ౔༵೔ͷேɺ
 ձࣾͷRuboCopઃఆͮ͘ΓΛ
 ͍ͯ͠·ͨ͠
  71. I've been thinking about the things I talked about today,

    
 and I thought about it again that morning
 
 ࠓ೔࿩ͨ͜͠ͱ͸ Ҏલ͔ΒԿճ͔ࢥ͍ͬͯ·͕ͨ͠ɺ ͜ͷ೔ͷே΋ߟ͑·ͨ͠
  72. Then I realized that day was the CFP deadline for

    ͪΐ͏Ͳͦͷ೔͕ɺCFPకΊ੾Γͷ೔ͩͬͨ
  73. I would be happy if it helps to realize a

    better RuboCop World ࠓ೔ͷτʔΫ͕ ΑΓྑ͍ RuboCop World ͷ ࣮ݱʹ໾ཱͬͨΒخ͍͠Ͱ͢