Refactoring. Ruby edition.Anatoli Makarevich
@makaroni4
Who am I?
Our projects look like
In next 15 minutes we will
• spice up our knowledge about refactoring
• look at some common smells
• get acquainted with automated code analysis
• become ready to refactor
Refactoring is
but NOT
writing testschanging code
reducing complexity
adding new features
Refactoring != Moving backwards
To grow fast you need to grow right.
What refactoring does?
ComplexityReadabilityMaintainabilityExtensibility
This is scientific!
Martin Fowler, 1999
Your desk books are:
Code Smell
Any symptom in the source code of a program that possibly indicates a deeper
problemKent Beck
Code smells
Long methodDuplicationsHeavy classStupid name
Too many params
Feature envyUbercallback
Complex conditions
Refactoring cycleCheck testcoverage
Write testsif needed
Change code
Ensure thattests pass
Check overallcomplexity
Find code smellsCheck testcoverage
Write testsif needed
Change code
Ensure thattests pass
Check overallcomplexity
Check test coverageCheck testcoverage
Write testsif needed
Change code
Ensure thattests pass
Check overallcomplexity
Write new tests if neededCheck testcoverage
Write testsif needed
Change code
Ensure thattests pass
Check overallcomplexity
reFACTORCheck testcoverage
Write testsif needed
Change code
Ensure thattests pass
Check overallcomplexity
Ensure that tests passCheck testcoverage
Write testsif needed
Change code
Ensure thattests pass
Check overallcomplexity
Automate tests!Check testcoverage
Write testsif needed
Change code
Ensure thattests pass
Check overallcomplexity
Travis CIJenkins CIGitlab CI
Automate complexity analysis?Check testcoverage
Write testsif needed
Change code
Ensure thattests pass
Check overallcomplexity
Could complexity analysis be automated?
?How can we process code?
s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))
S-expressions
s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))
Sexp operator
s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))
Sexp body
Automated analysis
• Long methods
• Complex class
• Stupid variable name
Long method
s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))
Find method Sexp :defn
Long method
s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))
Find method Sexp :defn
Count sexp operators
Complex class
s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))
Find method Sexp :class
Complex class
s(:class, :Sexp, s(:const, :Array), s(:defn, :sexp_type, s(:args), s(:call, nil, :first)), s(:defn, :sexp_body, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))
Find method Sexp :class
Cound weights of Sexp operators
Stupid variable name
s(:class, :HomerSimpson, s(:const, :BlahBlahBlah), s(:defn, :donuts, s(:args), s(:call, nil, :fist)), s(:defn, :beersnstuff, s(:args), s(:call, nil, :[], s(:lit, 1..-1))))
Automated analysis
Refactoring!=
Rehacktoring
@katrinyx
It is about perception
We READ code, NOT COMPILE it.
After this talk do:
• gem install flog
• gem install flay
• gem install reek
• flog PROJECT_PATH
• flay PROJECT_PATH
• reek PROJECT_PATH
Let’s refactor!
Anatoli Makarevich@makaroni4