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
In this talk I will talk about the problems that can arise in the development team using RuboCop and how to solve them RuboCopʢͷΑ͏ͳπʔϧʣΛ͏͜ͱͰ ։ൃνʔϜʹى͜ΓಘΔͱ ͦͷղܾํ๏ʹ͍ͭͯ͠·͢
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ʣΛ࡞ΓࠐΜͩ͜ͱͷ͋Δํ✋
• It checks your code and extract the problems ɹίʔυΛνΣοΫ͠ɺΛநग़ͯ͘͠Ε·͢ • Also has a function that fi xes problems automatically if possible ɹࣗಈͰमਖ਼ͯ͘͠ΕΔػೳ͋Γ·͢ https://github.com/rubocop/rubocop
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ͰΒͤͯɺ ɹҧ͕͋ΕϚʔδ͞Εͳ͍Α͏ʹ͢Δ
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 !!
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ϒϥϯνʹೖΔ҆৺ײ
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
Example 2 • Renaming makes it ambiguas in this case ɹ໊લΛม͑Δͱ͔͑ͬͯᐆດʹͳΔ class ParentModel < ApplicationRecord def has_child? … Naming/PredicateName: Rename has_child? to child? def child?
Beginners in the development team are forced to write code under the rules that they cannot judge for themselves ։ൃνʔϜͷॳ৺ऀɺ ࣗͰΑ͋͠͠ΛஅͰ͖ͳ͍ϧʔϧʹ ੍͞Εͳ͕ΒίʔυΛॻ͘͜ͱʹͳΔ
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Λ͏ͱ͖ ඞͣ͠ॳ৺ऀʹಧ͔ͳ͍
Under RuboCop, unskilled people might be trapped while skilled people are enjoying Ruby freely εΩϧͷ͋Δਓ RuboCopΛ͍ͬͯͯ RubyΛࣗ༝ʹָ͠ΊΔ͕ɺ εΩϧͷͳ͍ਓRuboCopʹڧ੍͘͞ΕΔ
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
Taking easier strategies • This may not solve the problem conclusively ɹͷ࠷ऴղܾʹͭͳ͕Βͣɺ ɹ·ͨ͜ͷίετΛ͏ඞཁ͕ൃੜ͢Δ͔͠Εͳ͍ 2. Change the rule in that code ɹͦͷίʔυͰϧʔϧΛม͑Δ 3. Just follow the rule ɹͱΓ·ɺϧʔϧʹै͓ͬͯ͘
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
"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ͬΆ͍ελΠϧΨΠυɺಈతͳͷͰͳ͍͔ʁ
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 ɹઃఆͷॊೈ͚ͩ͞ͰͦͷϦεΫΛճආͰ͖ͳ͍
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 Ұݟͯ͠ͷਖ਼͠͞Ͱͳ͘ɺ ະདྷʹॻ͔ΕΔίʔυؚΊͯ ͕ى͖ͳ͍͔ߟ͑Δඞཁ͕͋Δ
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ʹͰ ॻ͍͍͖͍ͯͨͱࢥ͍·͢
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 ɹࠓޙ৽͍͠ϧʔϧ͕Ճ͞ΕΔͨͼʹܧଓతʹબผ࡞ۀ
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ɺίʔυͷදʹελΠϧͱ͍͏֓೦͕ ͋ΓɺԿ͕ྑ͍ελΠϧ͔ৗʹ੩తʹܾΊΒΕΔͱ ͍͏ͷݟํΛ͍ͯ͠ΔΑ͏ʹײ͡Δ
The more willingly you detect points that could be improved, the more "rules that don't fi t the situation" you get վળͰ͖Δ͔͠Εͳ͍ϙΠϯτΛ ҙཉతʹݕग़͢Δ΄Ͳ ʮঢ়گʹ߹Θͳ͍ϧʔϧʯ͕ଟ͘ͳΔ
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 ɹڧ੍ʹΑΔμϝʔδΛ࠷খԽ͢Δͱɺ ɹίʔυվળͷػձݮͬͯ͠·͏
How to use Information Level ࢀߟϨϕϧͷ͍ํ • Regularly run in CI etc ɹCIͳͲͰఆظ࣮ߦ • Informative level violations should be labeled as "informative" not “violations" ɹࢀߟϨϕϧͰͷҧ ɹʮҧʯͰͳ͘ʮࢀߟใʯͱͯ͠දࣔ͢Δ
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 ɹڧ੍ʹΑΔμϝʔδΛ࠷খԽ͢Δͱɺ ɹίʔυվળͷػձݮͬͯ͠·͏
• 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 ɹઃఆ͕େม
It makes you feel much less guilty to think “the rule is for reference” than “the violation won't have to be fi xed” ʮͦͷϧʔϧࢀߟ༻ʹ͠Α͏ʯͷ΄͏͕ ʮҧΛ͞ͳ͍͍ͯ͘͜ͱʹ͠Α͏ʯΑΓ ͣͬͱࡑѱײ͕গͳ͍
We can have a nice information level code improvement suggestion system ࢀߟϨϕϧͷνΣοΫʹجͮ͘ ૉఢͳίʔυվળఏҊγεςϜΛ ར༻Ͱ͖Δͱ͍͍ͳ…ʢເʣ 3. Reducing damages also reduces the opportunities ɹڧ੍ʹΑΔμϝʔδΛ࠷খԽ͢Δͱɺ ɹίʔυվળͷػձݮͬͯ͠·͏
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
Make it easier to handle areas that cannot be determined by 0/1 0/1ͰఆͰ͖ͳ͍ྖҬΛѻ͍͘͢ (00% #"% .":#&(00% )VNBOTDBOBMTPSFWJFXBOEKVEHF Enforcement Information