first do no harm: surgical refactoring (extended edition)
TRANSCRIPT
![Page 1: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/1.jpg)
First Do No HarmSurgical Refactoring
Nell Shamrell-Harrington@nellshamrell
![Page 2: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/2.jpg)
Section I: Refactoring
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 3: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/3.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
Refactoring is a change and changes can go wrong
What is refactoring?
![Page 4: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/4.jpg)
But…it’s not life or death, right?
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 5: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/5.jpg)
But…it’s not life or death, right?
First Do No Harm: Surgical Refactoring @nellshamrell
Software is being integrated into…
![Page 6: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/6.jpg)
But…it’s not life or death, right?
First Do No Harm: Surgical Refactoring @nellshamrell
Software is being integrated into…
Transportation
![Page 7: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/7.jpg)
But…it’s not life or death, right?
First Do No Harm: Surgical Refactoring @nellshamrell
Software is being integrated into…
TransportationEnergy sources
![Page 8: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/8.jpg)
But…it’s not life or death, right?
First Do No Harm: Surgical Refactoring @nellshamrell
Software is being integrated into…
TransportationEnergy sourcesMedical Devices
![Page 9: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/9.jpg)
So…is refactoring bad, then?
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 10: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/10.jpg)
So…is refactoring bad, then?
First Do No Harm: Surgical Refactoring @nellshamrell
Refactoring is neither inherently good OR bad
![Page 11: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/11.jpg)
So…is refactoring bad, then?
First Do No Harm: Surgical Refactoring @nellshamrell
How you do it is what matters
![Page 12: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/12.jpg)
How should I refactor?
First Do No Harm: Surgical Refactoring @nellshamrell
2 Common Approaches
![Page 13: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/13.jpg)
How should I refactor?
First Do No Harm: Surgical Refactoring @nellshamrell
2 Common Approaches1) Edit and Pray
![Page 14: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/14.jpg)
How should I refactor?
First Do No Harm: Surgical Refactoring @nellshamrell
2 Common Approaches1) Edit and Pray
2) Cover and Modify
![Page 15: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/15.jpg)
How should I refactor?
First Do No Harm: Surgical Refactoring @nellshamrell
2 Common Approaches1) Edit and Pray
2) Cover and Modify- “Working Effectively with Legacy Code”
![Page 16: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/16.jpg)
Section II: Surgical Refactoring
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 17: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/17.jpg)
What is surgical refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Change exactly what we INTEND to changeAnd ONLY what we intend to change
![Page 18: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/18.jpg)
What is surgical refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
First do no harm!
![Page 19: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/19.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
Surgical refactoring is a series of good habits that reduce risk
What is surgical refactoring?
![Page 20: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/20.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
2 categories of refactoring
What is surgical refactoring?
![Page 21: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/21.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
2 categories of refactoring
What is surgical refactoring?
1) Necessary refactoring
![Page 22: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/22.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
2 categories of refactoring
What is surgical refactoring?
1) Necessary refactoring2) Cosmetic refactoring
![Page 23: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/23.jpg)
What is a necessary refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Need to add something
![Page 24: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/24.jpg)
What is a necessary refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Need to add somethingCode is too inefficient
![Page 25: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/25.jpg)
What is a necessary refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Need to add somethingCode is too inefficient
Blocked from achieving a business need
![Page 26: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/26.jpg)
What is a necessary refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Necessary refactorings have a moderate to high risk tolerance
![Page 27: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/27.jpg)
What is a cosmetic refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 28: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/28.jpg)
What is a cosmetic refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
No business need to change code
![Page 29: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/29.jpg)
What is a cosmetic refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Something about it just bugs usNo business need to change code
![Page 30: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/30.jpg)
What is a cosmetic refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Cosmetic refactorings have a low risk tolerance
![Page 31: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/31.jpg)
What about whitespace refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 32: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/32.jpg)
What about whitespace refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Ultimate cosmetic refactoring
![Page 33: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/33.jpg)
What about whitespace refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Ultimate cosmetic refactoring
Get a style guide (i.e. Github style guide)
![Page 34: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/34.jpg)
What about whitespace refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Ultimate cosmetic refactoring
Get a style guide (i.e. Github style guide)
If whitespace does not violate style guide, leave it alone!
![Page 35: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/35.jpg)
What’s involved in surgical refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 36: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/36.jpg)
What’s involved in surgical refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
1) Pre-op: what to do before touching the code
![Page 37: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/37.jpg)
What’s involved in surgical refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
1) Pre-op: what to do before touching the code 2) Operation: doing the actual refactoring
![Page 38: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/38.jpg)
What’s involved in surgical refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
1) Pre-op: what to do before touching the code 2) Operation: doing the actual refactoring
3) Recovery: verifying the refactor
![Page 39: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/39.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Thanks, @mikelorant!
![Page 40: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/40.jpg)
Section IV: Pre-Op
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 41: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/41.jpg)
What is involved in pre-op?
First Do No Harm: Surgical Refactoring @nellshamrell
Diagnosis (What exactly does the code do?)
![Page 42: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/42.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
![Page 43: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/43.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end Calls Ruby’s system method
![Page 44: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/44.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
endExecutes sed command with some flags
![Page 45: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/45.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Performs a substitution
![Page 46: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/46.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
endIn a series directories and files
![Page 47: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/47.jpg)
So…do we know what it does?
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 48: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/48.jpg)
So…do we know what it does?
First Do No Harm: Surgical Refactoring @nellshamrell
Map is influenced by our own experiences and expectations
![Page 49: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/49.jpg)
So…do we know what it does?
First Do No Harm: Surgical Refactoring @nellshamrell
Only definite way of knowing what the code does is to execute the code itself
![Page 50: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/50.jpg)
So…do we know what it does?
First Do No Harm: Surgical Refactoring @nellshamrell
Best way to repeatedly execute the code is through automated tests
![Page 51: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/51.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Now what does this system call do?
![Page 52: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/52.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:do_system_things) { DoSystemThings.new }
Instantiate the class
![Page 53: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/53.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:do_system_things) { DoSystemThings.new } let(:dir) { ‘something’ }
Sample argument to pass to class
![Page 54: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/54.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:do_system_things) { DoSystemThings.new } let(:dir) { ‘something’ }
describe ‘making the system call’ do it ‘calls the Ruby#system method’ do
end
end
![Page 55: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/55.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:do_system_things) { DoSystemThings.new } let(:dir) { ‘something’ }
describe ‘making the system call’ do it ‘calls the Ruby#system method’ do expect(do_system_things)
.to receive(:system).with(anything())
end end
Expect that our instance of the class
![Page 56: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/56.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
Will receive a system call with any args
let(:do_system_things) { DoSystemThings.new } let(:dir) { ‘something’ }
describe ‘making the system call’ do it ‘calls the Ruby#system method’ do expect(do_system_things)
.to receive(:system).with(anything())
end end
![Page 57: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/57.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:do_system_things) { DoSystemThings.new } let(:dir) { ‘something’ }
describe ‘making the system call’ do it ‘calls the Ruby#system method’ do expect(do_system_things)
.to receive(:system).with(anything()) do_system_things.do_the_thing(dir)
end end Call the method
![Page 58: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/58.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:do_system_things) { DoSystemThings.new } let(:dir) { ‘something’ }
describe ‘making the system call’ do it ‘calls the Ruby#system method’ do expect(do_system_things)
.to receive(:system).with(anything()) do_system_things.do_the_thing(dir)
end end
Spec Passes!
![Page 59: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/59.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Remove the system call
![Page 60: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/60.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Spec Fails!
![Page 61: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/61.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Put the system call back
![Page 62: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/62.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Spec Passes!
![Page 63: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/63.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
endWhat return is expected?
![Page 64: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/64.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end Rdocs: system method returns true when the command executes successfully
![Page 65: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/65.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:dir) { ‘something’ }
context ‘when the method call is successful’ do it ‘returns true’ do end end
![Page 66: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/66.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:dir) { ‘something’ }
context ‘when the method call is successful’ do it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end end
Expect the return from calling the method on the instance of the class
![Page 67: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/67.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:dir) { ‘something’ }
context ‘when the method call is successful’ do it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end end
To return true
![Page 68: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/68.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
let(:dir) { ‘something’ }
context ‘when the method call is successful’ do it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end end
Spec Fails!
![Page 69: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/69.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
'sed: directory/*/.rb: No such file or directory'
let(:dir) { ‘something’ }
context ‘when the method call is successful’ do it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end end
![Page 70: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/70.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
context ‘when the method call is successful’ do let(:directory_name) { ‘some_directory’ } let(:sub_directory) { ‘some_sub_directory’ } let(:file) { ‘some_file.rb’ }
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end end
Set the directory, subdirectory, and file names
![Page 71: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/71.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
context ‘when the method call is successful’ do let(:directory_name) { ‘some_directory’ } let(:sub_directory) { ‘some_sub_directory’ } let(:file) { ‘some_file.rb’ }
before do FileUtils.mkdir_p(File.join(directory_name, sub_directory)) end
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end end
Create directories and sub-directories
![Page 72: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/72.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
context ‘when the method call is successful’ do let(:directory_name) { ‘some_directory’ } let(:sub_directory) { ‘some_sub_directory’ } let(:file) { ‘some_file.rb’ }
before do FileUtils.mkdir_p(File.join(directory_name, sub_directory)) path = File .join(directory_name,subdirectory_name,file_name) end
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end end
Create the path for the file
![Page 73: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/73.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
context ‘when the method call is successful’ do let(:directory_name) { ‘some_directory’ } let(:sub_directory) { ‘some_sub_directory’ } let(:file) { ‘some_file.rb’ }
before do FileUtils.mkdir_p(File.join(directory_name, sub_directory)) path = File .join(directory_name,subdirectory_name,file_name) file = File.new(path, ‘w’) file.write(‘look, there is something in this file’) file.close end
it ‘returns true’ do
Create the actual file
![Page 74: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/74.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
context ‘when the method call is successful’ do let(:directory_name) { ‘some_directory’ } let(:sub_directory) { ‘some_sub_directory’ } let(:file) { ‘some_file.rb’ }
before do FileUtils.mkdir_p(File.join(directory_name, sub_directory)) path = File .join(directory_name,subdirectory_name,file_name) file = File.new(path, ‘w’) file.write(‘look, there is something in this file’) file.close end
it ‘returns true’ do
Spec Passes!
![Page 75: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/75.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
context ‘when the method call is successful’ do let(:directory_name) { ‘some_directory’ } let(:sub_directory) { ‘some_sub_directory’ } let(:file) { ‘some_file.rb’ }
before do FileUtils.mkdir_p(File.join(directory_name, sub_directory)) path = File .join(directory_name,subdirectory_name,file_name) file = File.new(path, ‘w’) file.write(‘look, there is something in this file’) file.close end
it ‘returns true’ do
That’s a lot of setup code…
![Page 76: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/76.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
def create_required_directories_and_files(path, filename) FileUtils.mkdir_p(File.join(path)) file = File.new(File.join(path,file_name), ‘w’) file.write(‘look, there is something in this file’) file.close end Takes a path and
file name
![Page 77: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/77.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
def create_required_directories_and_files(path, filename) FileUtils.mkdir_p(File.join(path)) file = File.new(File.join(path,file_name), ‘w’) file.write(‘look, there is something in this file’) file.close end Makes the directories
![Page 78: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/78.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
def create_required_directories_and_files(path, filename) FileUtils.mkdir_p(File.join(path)) file = File.new(File.join(path,file_name), ‘w’) file.write(‘look, there is something in this file’) file.close end
Makes the file
![Page 79: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/79.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
before do create_required_directories_and_files( File.join(directory_name,subdirectory_name), file_name ) end
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end
Call the setup method
![Page 80: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/80.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
before do create_required_directories_and_files( File.join(directory_name,subdirectory_name), file_name ) end
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end
Create and pass the path for the file
![Page 81: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/81.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
before do create_required_directories_and_files( File.join(directory_name,subdirectory_name), file_name ) end
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end Pass the file name
![Page 82: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/82.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
before do create_required_directories_and_files( File.join(directory_name,subdirectory_name), file_name ) end
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true)
end
Spec Passes!
![Page 83: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/83.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
before do create_required_directories_and_files( File.join(directory_name,subdirectory_name), file_name ) end
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true) end
after do FileUtils.rm_rf(directory_name) end Remove created
directories and file
![Page 84: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/84.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
before do create_required_directories_and_files( File.join(directory_name,subdirectory_name), file_name ) end
it ‘returns true’ do expect(do_system_things.do_the_thing(dir)).to eq(true) end
after do FileUtils.rm_rf(directory_name) end
Spec Passes!
![Page 85: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/85.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
*pause*
![Page 86: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/86.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
sed is a streaming text editor
![Page 87: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/87.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
![Page 88: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/88.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
Find match for this pattern
s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g'
![Page 89: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/89.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
Replace it with this pattern
s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g'
![Page 90: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/90.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string)
end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
![Page 91: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/91.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) //.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
![Page 92: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/92.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
end
![Page 93: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/93.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘'}
end
![Page 94: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/94.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {''} it 'matches a string' do
end end
![Page 95: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/95.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {''} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
![Page 96: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/96.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) //.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Returns nil if no successful match
![Page 97: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/97.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {''} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
Means it found a successful match
![Page 98: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/98.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {''} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
first character is ‘:’
![Page 99: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/99.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end add ‘:’ to string
![Page 100: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/100.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
Spec Fails!
![Page 101: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/101.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
add ‘:’ to regex
![Page 102: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/102.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Spec Passes!
![Page 103: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/103.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
Next character is alnum character class
![Page 104: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/104.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:a'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end Add letter to test string
![Page 105: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/105.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
Spec Fails!
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:a'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
![Page 106: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/106.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:[[:alnum:]]/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
add alnum to regex
![Page 107: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/107.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:[[:alnum:]]/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Spec Passes!
![Page 108: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/108.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:a'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end Means character must
appear one or more times
![Page 109: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/109.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
Add character to test string
![Page 110: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/110.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
Spec Passes!
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
![Page 111: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/111.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
But…we were expecting a failure…
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string)) .not_to be_nil end end
![Page 112: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/112.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:[[:alnum:]]/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end Will return successful match with only one alnum character
![Page 113: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/113.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string) .to_s).to include(‘:ab’) end
end
Examining content of string that was captured by the regex
![Page 114: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/114.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
Spec Fails!
describe ‘what the regex matches’ # FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string) .to_s).to include(‘:ab’) end
end
![Page 115: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/115.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:[[:alnum:]]+/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
add + quantifier
![Page 116: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/116.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:[[:alnum:]]+/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Spec Passes!
![Page 117: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/117.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
# FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string) .to_s).to include(‘:ab’) end
Capture group
![Page 118: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/118.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
# FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string) .to_s).to include(‘:ab’) end
it ‘captures a group’ do
end
![Page 119: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/119.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
# FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string) .to_s).to include(‘:ab’) end
it ‘captures a group’ do expect(do_system_things.first_regex_match(string)[1]) .not_to be_nil end Testing that match captures
a capture group ([1] references first capture group)
![Page 120: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/120.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
Spec Fails!
# FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string) .to_s).to include(‘:ab’) end
it ‘captures a group’ do expect(do_system_things.first_regex_match(string)[1]) .not_to be_nil end
![Page 121: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/121.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:[[:alnum:]]+()/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
endAdding empty capture group
![Page 122: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/122.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:[[:alnum:]]+()/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Spec Passes!
![Page 123: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/123.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
# FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string) .to_s).to include(‘:ab’) end
it ‘captures a group’ do expect(do_system_things.first_regex_match(string)[1]) .not_to be_nil expect(do_system_things.first_regex_match(string)[1]) .to eq(‘ab’) end
Testing content of capture group
![Page 124: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/124.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rb
Spec Fails!
# FOR REFERENCE: /:([[:alnum:]]+)[[:space:]]=>/
let(:string) {‘:ab'} it 'matches a string' do expect(do_system_things.first_regex_match(string) .to_s).to include(‘:ab’) end
it ‘captures a group’ do expect(do_system_things.first_regex_match(string)[1]) .not_to be_nil expect(do_system_things.first_regex_match(string)[1]) .to eq(‘ab’) end
![Page 125: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/125.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:([[:alnum:]]+)/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
endPlacing capture group in correct place
![Page 126: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/126.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:([[:alnum:]]+)/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
Spec Passes!
![Page 127: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/127.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:([[:alnum:]]+)[[:space]]=>/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end Fast Forward… (Adding in tests for rest of characters)
![Page 128: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/128.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def first_regex_match(string) /:([[:alnum:]]+)[[:space]]=>/.match(string) end
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end We know what this regex does! ‘:ab =>’ matches!
![Page 129: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/129.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do before do file = File.open(File.join(directory_path,file_name)) file.write(':ab =>') file.close end end
Write sample string to file (note the space and hash rocket)
![Page 130: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/130.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do it ‘changes the file’ do original_contents = File.read(File.join(directory_path,file_name))
end end
Capture original contents of file
![Page 131: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/131.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do it ‘changes the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things.do_the_thing(directory_name)
end end Call the method
![Page 132: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/132.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do it ‘changes the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things.do_the_thing(directory_name)
new_contents = File.read (File.join(directory_path,file_name)) end end
Capture new contents of file
![Page 133: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/133.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do it ‘changes the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things.do_the_thing(directory_name)
new_contents = File.read (File.join(directory_path,file_name)) expect(original_contents).not_to eq(new_contents) end end
Make sure file changes
![Page 134: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/134.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do it ‘changes the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things.do_the_thing(directory_name)
new_contents = File.read (File.join(directory_path,file_name)) expect(original_contents).not_to eq(new_contents) end end
Spec Passes!
![Page 135: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/135.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
*pause*
![Page 136: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/136.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
Replace match for the first pattern with this second pattern
s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g'
![Page 137: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/137.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
\\1:
![Page 138: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/138.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
\\1:
Escape - so we can use a literal \ as the next character
![Page 139: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/139.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
\\1:
Uses the result of the first capture group from the first pattern
![Page 140: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/140.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
\\1:
Adds a literal colon
![Page 141: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/141.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g'
‘:ab =>’
![Page 142: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/142.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g'
‘ab:’‘:ab =>’ replace with
![Page 143: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/143.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do let(:orig_string) { “:ab => “} let(:new_string) { “ab: ‘}
it ‘changes the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things.do_the_thing(directory_name)
new_contents = File.read(File.join(directory_path,file_name)) end end
Expected content of file before and after
![Page 144: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/144.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do let(:orig_string) { “:ab => “} let(:new_string) { “ab: ‘}
it ‘changes the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things.do_the_thing(directory_name)
new_contents = File.read(File.join(directory_path,file_name)) expect(new_contents).not_to include(orig_string) expect(new_contents).to include(new_string) end end
Verify contents of modified file
![Page 145: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/145.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do let(:orig_string) { “:ab => “} let(:new_string) { “ab: ‘}
it ‘changes the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things.do_the_thing(directory_name)
new_contents = File.read(File.join(directory_path,file_name)) expect(new_contents).not_to include(orig_string) expect(new_contents).to include(new_string) end end Spec Passes!
![Page 146: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/146.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
*pause*
![Page 147: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/147.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g'
Replace all matches for the first pattern with the second pattern
![Page 148: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/148.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do let(:orig_string) { “:ab => :ab =>“} let(:new_string) { “ab: ab:’}
it ‘changes all matches within the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things.do_the_thing(directory_name)
new_contents = File.read(File.join(directory_path,file_name)) expect(new_contents).not_to include(orig_string) expect(new_contents).to include(new_string) end end
Expected content of file before and after
![Page 149: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/149.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do let(:orig_string) { “:ab => :ab =>“} let(:new_string) { “ab: ab:’}
it ‘changes all matches within the file’ do original_contents = File.read(File.join(directory_path,file_name))
do_system_things(directory_name)
new_contents = File.read(File.join(directory_path,file_name)) expect(new_contents).not_to include(orig_string) expect(new_contents).to include(new_string) end end Spec Passes!
![Page 150: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/150.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/" #{dir}/**/*.rb" end
end
Taking out the global flag
![Page 151: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/151.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/" #{dir}/**/*.rb" end
end
Spec Fails!
![Page 152: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/152.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
Putting the flag back in
![Page 153: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/153.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
Spec Passes!
![Page 154: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/154.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
Next step…add in tests for these flags
![Page 155: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/155.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # taking the -E flag out system "sed -i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
![Page 156: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/156.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # taking the -E flag out system "sed -i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
Spec Fails!
![Page 157: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/157.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # putting the -E flag back in system "sed E —i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
![Page 158: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/158.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # putting the -E flag back in system "sed E —i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
![Page 159: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/159.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # putting the -E flag back in system "sed E —i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
Spec Passes!
![Page 160: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/160.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed E —i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
![Page 161: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/161.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do
it ‘does not save a backup copy of the file’ do # Expect the subdirectory we created to contain only one file expect(Dir[“#{directory_name}/#{subdirectory_name}/*”] .count).to eq(1)
end end
![Page 162: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/162.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do
it ‘does not save a backup copy of the file’ do # Expect the subdirectory we created to contain only one file expect(Dir[“#{directory_name}/#{subdirectory_name}/*”] .count).to eq(1)
do_system_things.do_the_thing(directory_name)
end end
![Page 163: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/163.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do
it ‘does not save a backup copy of the file’ do # Expect the subdirectory we created to contain only one file expect(Dir[“#{directory_name}/#{subdirectory_name}/*”] .count).to eq(1)
do_system_things.do_the_thing(directory_name)
expect(Dir[“#{directory_name}/#{subdirectory_name}/*”] .count).to eq(1) end end
![Page 164: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/164.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
spec/do_system_things_spec.rbcontext ‘changing the file’ do
it ‘does not save a backup copy of the file’ do # Expect the subdirectory we created to contain only one file expect(Dir[“#{directory_name}/#{subdirectory_name}/*”] .count).to eq(1)
do_system_things.do_the_thing(directory_name)
expect(Dir[“#{directory_name}/#{subdirectory_name}/*”] .count).to eq(1) end end
Spec Passes!
![Page 165: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/165.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # adding an extension to the -i flag system "sed E —i .tmp ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
![Page 166: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/166.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # adding an extension to the -i flag system "sed E —i .tmp ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb” end
end
Spec Fails!
![Page 167: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/167.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # removing extension to -i flag system "sed E —i ‘’ ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
![Page 168: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/168.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) # removing extension to -i flag system "sed E —i ‘’ ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
Spec Passes!
![Page 169: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/169.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' ’s/:([[:alnum:]]+)[[:space:]]=>/\\1:/g" #{dir}/**/*.rb" end
end
We know what this does!
![Page 170: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/170.jpg)
Section V: Operation
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 171: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/171.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
![Page 172: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/172.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
end
![Page 173: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/173.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' #{dir}/**/*.rb" end
private
def substitute_command 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' end
end
![Page 174: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/174.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' #{substitute_command} #{dir}/**/*.rb" end
private
def substitute_command 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' end
end
![Page 175: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/175.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' #{substitute_command} #{dir}/**/*.rb" end
private
def substitute_command 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' end
end
Specs Pass!
![Page 176: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/176.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' #{substitute_command} #{dir}/**/*.rb" end
private
def substitute_command 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' end
end Really old regex syntax
![Page 177: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/177.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' #{substitute_command} #{dir}/**/*.rb" end
private
def substitute_command ’s/:(\w+)\s=>/\\1:/g’ end
end New regex syntax
![Page 178: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/178.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' #{substitute_command} #{dir}/**/*.rb" end
private
def substitute_command ’s/:(\w+)\s=>/\\1:/g’ end
end Specs Fail!
\w != [:alnum]
![Page 179: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/179.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' #{substitute_command} #{dir}/**/*.rb" end
private
def substitute_command 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' end
end Back to the old regex syntax
![Page 180: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/180.jpg)
First Do No Harm: Surgical Refactoring @nellshamrell
lib/do_system_things.rb
class DoSystemThings
def do_the_thing(dir) system "sed -E -i '' #{substitute_command} #{dir}/**/*.rb" end
private
def substitute_command 's/:([[:alnum:]]+)[[:space:]]=>/\\1:/g' end
end
Specs Pass!
![Page 181: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/181.jpg)
Section VI: Recovery
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 182: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/182.jpg)
What do I need to do after refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Need to know two things decisively
![Page 183: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/183.jpg)
What do I need to do after refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Need to know two things decisively 1) Does the behavior still exist?
![Page 184: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/184.jpg)
What do I need to do after refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Need to know two things decisively 1) Does the behavior still exist?
2) Is it connected correctly?
![Page 185: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/185.jpg)
What do I need to do after refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
What about QA?
![Page 186: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/186.jpg)
What do I need to do after refactoring?
First Do No Harm: Surgical Refactoring @nellshamrell
Ideally, QA should find nothing
![Page 187: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/187.jpg)
What if something goes wrong?
First Do No Harm: Surgical Refactoring @nellshamrell
![Page 188: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/188.jpg)
What if something goes wrong?
First Do No Harm: Surgical Refactoring @nellshamrell
1) Take responsibility - what your code does in production is your responsibility
![Page 189: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/189.jpg)
What if something goes wrong?
First Do No Harm: Surgical Refactoring @nellshamrell
1) Take responsibility - what your code does in production is your responsibility
2) Evaluate risk of another change (a change to a change is still a change)
![Page 190: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/190.jpg)
What if something goes wrong?
First Do No Harm: Surgical Refactoring @nellshamrell
1) Take responsibility - what your code does in production is your responsibility
2) Evaluate risk of another change (a change to a change is still a change)
3) Fix the problem (if you can’t, find someone who can!)
![Page 191: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/191.jpg)
Conclusion
First Do No Harm: Surgical Refactoring @nellshamrell
“I’m not a great programmer, I’m just a good programmer with great habits”
- “Refactoring: Ruby Edition”
![Page 192: First Do No Harm: Surgical Refactoring (extended edition)](https://reader031.vdocuments.site/reader031/viewer/2022020410/5875f1b01a28ab006e8b50e5/html5/thumbnails/192.jpg)
Thank You!
First Do No Harm: Surgical Refactoring @nellshamrell
Nell Shamrell-Harrington
Software Development Engineer at Chef
@nellshamrell
www.nellshamrell.com