Therapeutic refactoring

287
Therapeutic Refactoring Katrina Owen @kytrinyx github.com/kytrinyx/therapeutic-refactoring

description

Slides for the Therapeutic Refactoring talk presented at NordicRuby on June 15th, 2012, and Scottish Ruby Conference on June 30th, 2012. The code samples are on github: http://github.com/kytrinyx/therapeutic-refactoring

Transcript of Therapeutic refactoring

Page 1: Therapeutic refactoring

Therapeutic Refactoring

Katrina [email protected]/kytrinyx/therapeutic-refactoring

Page 2: Therapeutic refactoring

Illustration from Am Adult by Allie Broshhttp://hyperboleandahalf.blogspot.com/2010/03/am-adult.html

Page 3: Therapeutic refactoring

Photo: Johanna Owen 2011

Page 4: Therapeutic refactoring

Illustration from U B Hatin’ by Allie Broshhttp://hyperboleandahalf.blogspot.com/2010/03/u-b-hatin.html

Page 5: Therapeutic refactoring

I❤refactoring

Page 8: Therapeutic refactoring

refactoringis not

rehacktoring

Page 9: Therapeutic refactoring

Inspired by true events

A Story

Page 10: Therapeutic refactoring

Illustration from The Scariest Story by Allie Broshhttp://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html

Page 11: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 12: Therapeutic refactoring

Illustration from The Scariest Story by Allie Broshhttp://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html

Page 13: Therapeutic refactoring

Illustration from The Scariest Story by Allie Broshhttp://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html

Page 14: Therapeutic refactoring

Illustration from The Scariest Story by Allie Broshhttp://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html

Page 15: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 16: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 17: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 18: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 19: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 20: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 21: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 22: Therapeutic refactoring

(the first middle)

Tests

Page 23: Therapeutic refactoring

describe XYZService doend

Page 24: Therapeutic refactoring

describe XYZService do

it "works" do end

end

Page 25: Therapeutic refactoring

describe XYZService do

subject { XYZService.xyz_filename(stub) }

it "works" do end

end

Page 26: Therapeutic refactoring

describe XYZService do

subject { XYZService.xyz_filename(stub) }

it "works" do end

end

Page 27: Therapeutic refactoring

describe XYZService do

subject { XYZService.xyz_filename(stub) }

it "works" do end

end

Page 28: Therapeutic refactoring

describe XYZService do

subject { XYZService.xyz_filename(stub) }

it "works" do subject.should eq("something") end

end

Page 29: Therapeutic refactoring

subject.should eq "something"

Page 30: Therapeutic refactoring

subject.should eq "whatever"

Page 31: Therapeutic refactoring

subject.should eq "freddy"

Page 32: Therapeutic refactoring

subject.should eq "something"

Page 33: Therapeutic refactoring

Failures:

1) XYZService works

Failure/Error: subject.should eq("something")

Stub received unexpected message :publish_on with (no args)

# ./xyz_service.rb:6:in `xyz_filename'

Page 34: Therapeutic refactoring

Failures:

1) XYZService works

Failure/Error: subject.should eq("something")

Stub received unexpected message :publish_on with (no args)

# ./xyz_service.rb:6:in `xyz_filename'

Page 35: Therapeutic refactoring

Stub received unexpected message

:publish_onwith (no args)

Page 36: Therapeutic refactoring

Failures:

1) XYZService works

Failure/Error: subject.should eq("something")

Stub received unexpected message :publish_on with (no args)

# ./xyz_service.rb:6:in `xyz_filename'

Page 37: Therapeutic refactoring

# ./xyz_service.rb:6

Page 38: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 39: Therapeutic refactoring

target.publish_on.strftime("%d")

Page 40: Therapeutic refactoring

target.publish_on.strftime("%d")

Page 41: Therapeutic refactoring

target.publish_on.strftime("%d")

Page 42: Therapeutic refactoring

describe XYZService do

subject { XYZService.xyz_filename(stub) }

it "works" do end

end

Page 43: Therapeutic refactoring

describe XYZService do

subject { XYZService.xyz_filename(target) }

it "works" do end

end

Page 44: Therapeutic refactoring

describe XYZService do

let(:target) do stub(:target) end

subject { XYZService.xyz_filename(target) }

it "works" do subject.should eq("something") end

end

Page 45: Therapeutic refactoring

describe XYZService do

let(:target) do messages = { } stub(:target, messages) end

subject { XYZService.xyz_filename(target) }

it "works" do subject.should eq("something") end

end

Page 46: Therapeutic refactoring

describe XYZService do

let(:target) do messages = { :publish_on => ? } stub(:target, messages) end

subject { XYZService.xyz_filename(target) }

it "works" do subject.should eq("something") end

end

Page 47: Therapeutic refactoring

describe XYZService do

let(:target) do messages = { :publish_on => Date.new(2012, 3, 14) } stub(:target, messages) end

subject { XYZService.xyz_filename(target) }

it "works" do subject.should eq("something") end

end

Page 48: Therapeutic refactoring

Stub received unexpected message

:xyz_category_prefixwith (no args)

Page 49: Therapeutic refactoring

...

:xyz_category_prefix => ?,

...

Page 50: Therapeutic refactoring

...

:xyz_category_prefix => 'abc',

...

Page 51: Therapeutic refactoring

Stub received unexpected message

:kindwith (no args)

Page 52: Therapeutic refactoring

...

:kind => ?

...

Page 53: Therapeutic refactoring

...

:kind => 'unicorn'

...

Page 54: Therapeutic refactoring

Stub received unexpected message

:personal?with (no args)

Page 55: Therapeutic refactoring

...

:personal? => ?

...

Page 56: Therapeutic refactoring

...

:personal? => false

...

Page 57: Therapeutic refactoring

Stub received unexpected message

:idwith (no args)

Page 58: Therapeutic refactoring

...

:id => ?

...

Page 59: Therapeutic refactoring

...

:id => 1337

...

Page 60: Therapeutic refactoring

Stub received unexpected message

:titlewith (no args)

Page 61: Therapeutic refactoring

...

:title => ?

...

Page 62: Therapeutic refactoring

...

:title => 'magic & superglue'

...

Page 63: Therapeutic refactoring

Failures:

1) XYZService works

Failure/Error: subject.should eq("something")

expected: "something"

got: "14abcunicorn_1337_3f4894ca_magicsuper.jpg"

(compared using ==)

# ./xyz_file_spec.rb:18:in `block (2 levels) in <top (required)>

Page 64: Therapeutic refactoring

Failures:

1) XYZService works

Failure/Error: subject.should eq("something")

expected: "something"

got: "14abcunicorn_42_3f4894ca_magicsuper.jpg"

(compared using ==)

# ./xyz_file_spec.rb:18:in `block (2 levels) in <top (required)>

#WIN

Page 65: Therapeutic refactoring

let(:target) do messages = { :publish_on => Date.new(2012, 3, 14), :xyz_category_prefix => 'abc', :kind => 'unicorn', :personal? => false, :id => 1337, :title => 'magic & superglue' } stub(:target, messages) end

Page 66: Therapeutic refactoring

Failures:

1) XYZService works

Failure/Error: subject.should eq("something")

expected: "something"

got: "14abcunicorn_1337_3f4894ca_magicsuper.jpg"

(compared using ==)

# ./xyz_file_spec.rb:18:in `block (2 levels) in <top (required)>

Page 67: Therapeutic refactoring

Failures:

1) XYZService works

Failure/Error: subject.should eq("something")

expected: "something"

got: "14abcunicorn_1337_3f4894ca_magicsuper.jpg"

(compared using ==)

# ./xyz_file_spec.rb:18:in `block (2 levels) in <top (required)>

Page 68: Therapeutic refactoring

"14abcunicorn_1337_3f4894ca_magicsuper.jpg"

Page 69: Therapeutic refactoring

14abcunicorn_1337_3f4894ca_magicsuper.jpg

Page 70: Therapeutic refactoring

subject.should eq "14abcunicorn_1337_3f4894ca_magicsuper.jpg"

Page 71: Therapeutic refactoring

expected

"14abcunicorn_1337_3f4894ca_magicsuper.jpg"

got

"14abcunicorn_1337_59a2b50d_magicsuper.jpg"

Page 72: Therapeutic refactoring

expected

"14abcunicorn_1337_3f4894ca_magicsuper.jpg"

got

"14abcunicorn_1337_59a2b50d_magicsuper.jpg"

Page 73: Therapeutic refactoring

subject.should eq "14abcunicorn_1337_3f4894ca_magicsuper.jpg"

Page 74: Therapeutic refactoring

subject.should match/14abcunicorn_1337_[0-9a-f]{8}_magicsuper.jpg/

Page 75: Therapeutic refactoring

.

Finished in 0.00073 seconds

1 example, 0 failures

Page 76: Therapeutic refactoring

.

Finished in 0.00073 seconds

1 example, 0 failures#WIN

Page 77: Therapeutic refactoring

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

Page 78: Therapeutic refactoring

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

Page 79: Therapeutic refactoring

Illustration from The Scariest Story by Allie Broshhttp://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html

Page 80: Therapeutic refactoring

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

Page 81: Therapeutic refactoring

target.publish_on.strftime("%d")

Page 82: Therapeutic refactoring

:publish_on => Date.new(2012, 3, 14)

Page 83: Therapeutic refactoring

:publish_on => Date.new(2012, 2, 7)

Page 84: Therapeutic refactoring

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

Page 85: Therapeutic refactoring

target.kind.gsub("_", "")

Page 86: Therapeutic refactoring

:kind => 'unicorn'

Page 87: Therapeutic refactoring

:kind => 'magic_unicorn'

Page 88: Therapeutic refactoring

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

Page 89: Therapeutic refactoring

target.title.gsub(/[^\[a-z\]]/i, '').

downcase

Page 90: Therapeutic refactoring

:title => 'magic & superglue'

Page 91: Therapeutic refactoring

:title => 'I <3 Sparkles!!1!'

Page 92: Therapeutic refactoring

Illustration from Bycicle by Allie Broshhttp://hyperboleandahalf.blogspot.no/2010/07/bicycle.html

Page 93: Therapeutic refactoring

target.title.gsub(/[^\[a-z\]]/i, '').

downcase

Page 94: Therapeutic refactoring

target.title.gsub(/[^\[a-z\]]/i, '').

downcase

Page 95: Therapeutic refactoring

it "works" { ... } it "leaves square brackets???"

Page 96: Therapeutic refactoring

it "leaves square brackets???" do target.stub(:title => 'i[sparkle]s') end

Page 97: Therapeutic refactoring

expected

"07abcmagicunicorn_1337_f3b6d325_i[sparkle].jpg"

to match

/07abcmagicunicorn_1337_[0-9a-z]{8}_isparkles.jpg/

Page 98: Therapeutic refactoring

it "works"{ ... } it "leaves square brackets"{ ... }

Page 99: Therapeutic refactoring

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

Page 100: Therapeutic refactoring

"_%03d" % (target.age || 0)

if target.personal?

Page 101: Therapeutic refactoring

"_%03d" % (target.age || 0)

if target.personal?

Page 102: Therapeutic refactoring

it "works" { ... } it "leaves square brackets"{ ... } it "personalizes"

Page 103: Therapeutic refactoring

it "personalizes" do target.stub(:personal? => true) end

Page 104: Therapeutic refactoring

Stub received unexpected message

:agewith (no args)

Page 105: Therapeutic refactoring

it "personalizes" do target.stub(:personal? => true) target.stub(:age? => 42) end

Page 106: Therapeutic refactoring

"_%03d" % (target.age || 0)

if target.personal?

Page 107: Therapeutic refactoring

"_%03d" % (target.age || 0)

if target.personal?

Page 108: Therapeutic refactoring

it "works"{ ... } it "leaves square brackets"{ ... } it "personalizes"{ ... } it "handles nil age"

Page 109: Therapeutic refactoring

it "handles nil age" do target.stub(:personal? => true) target.stub(:age? => nil) end

Page 110: Therapeutic refactoring

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

Page 111: Therapeutic refactoring

length > 9 ? 9 : length

Page 112: Therapeutic refactoring

:title => 'I <3 Sparkles!!1!'

Page 113: Therapeutic refactoring

:title => 'I <3 SPARKLY Sparkles!!1!'

Page 114: Therapeutic refactoring

it "works" { ... } it "leaves square brackets" { ... } it "personalizes" { ... } it "handles nil age" { ... } it "handles short titles"

Page 115: Therapeutic refactoring

it "handles short titles" do target.stub(:title => ‘O HAI’) end

Page 116: Therapeutic refactoring

.....

Finished in 0.00386 seconds

5 examples, 0 failures

Page 117: Therapeutic refactoring

.....

Finished in 0.00386 seconds

5 examples, 0 failures#WIN

Page 118: Therapeutic refactoring

Illustration from This is Why I’ll Never be an Adult by Allie Broshhttp://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html

Page 119: Therapeutic refactoring

(the second middle)

Refactoring

Page 120: Therapeutic refactoring

replace methodwith method object

Refactoring

Page 121: Therapeutic refactoring

class XYZFileend

Page 122: Therapeutic refactoring

class XYZFile

def initialize(target) end

end

Page 123: Therapeutic refactoring

class XYZFile

attr_reader :target def initialize(target) @target = target end

end

Page 124: Therapeutic refactoring

class XYZFile

attr_reader :target def initialize(target) @target = target end

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 125: Therapeutic refactoring

class XYZFile

...

def self.xyz_filename(target) ... end

end

Page 126: Therapeutic refactoring

class XYZFile

...

def xyz_filename(target) ... end

end

Page 127: Therapeutic refactoring

class XYZFile

...

def name(target) ... end

end

Page 128: Therapeutic refactoring

class XYZFile

...

def name ... end

end

Page 129: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 130: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) end

end

Page 131: Therapeutic refactoring

require_relative './xyz_file'

module XYZService

def self.xyz_filename(target) end

end

Page 132: Therapeutic refactoring

require_relative './xyz_file'

module XYZService

def self.xyz_filename(target) XYZFile.new end

end

Page 133: Therapeutic refactoring

require_relative './xyz_file'

module XYZService

def self.xyz_filename(target) XYZFile.new end

end

(target)(target)

Page 134: Therapeutic refactoring

require_relative './xyz_file'

module XYZService

def self.xyz_filename(target) XYZFile.new end

end

(target)(target).name

Page 135: Therapeutic refactoring

.....

Finished in 0.00398 seconds

5 examples, 0 failures

Page 136: Therapeutic refactoring

.....

Finished in 0.00398 seconds

5 examples, 0 failures#WIN

Page 137: Therapeutic refactoring

class XYZFile ... def name # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 138: Therapeutic refactoring

class XYZFile ... def name # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 139: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 140: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 141: Therapeutic refactoring

class XYZFile ... def name ... truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" ... end

end

Page 142: Therapeutic refactoring

class XYZFile ... def name ... truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" ... end

end

Page 143: Therapeutic refactoring

class XYZFile ... def name ... truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" ... end

def truncated_title end

end

Page 144: Therapeutic refactoring

class XYZFile ... def name ... truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" ... end

def truncated_title truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" end

end

Page 145: Therapeutic refactoring

class XYZFile ... def name...

def truncated_title truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" end

end

Page 146: Therapeutic refactoring

class XYZFile ... def name...

def truncated_title truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" end

end

Page 147: Therapeutic refactoring

class XYZFile ... def name...

def truncated_title truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" end

end

Page 148: Therapeutic refactoring

class XYZFile ... def name...

def truncated_title truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length truncated_title[0..(truncate_to)] end

end

Page 149: Therapeutic refactoring

class XYZFile ... def name...

def truncated_title truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length truncated_title[0..(truncate_to)] end

end

Page 150: Therapeutic refactoring

class XYZFile ... def name ... truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" ... end

def truncated_title...

end

Page 151: Therapeutic refactoring

class XYZFile ... def name ... truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title}" ... end

def truncated_title...

end

Page 152: Therapeutic refactoring

class XYZFile ... def name ... truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title}" ... end

def truncated_title...end

Page 153: Therapeutic refactoring

class XYZFile ... def name ... filename << "_#{truncated_title}" ... end

def truncated_title...

end

Page 154: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def truncated_title...

end

Page 155: Therapeutic refactoring

class XYZFile ... def truncated_title truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length truncated_title[0..(truncate_to)] end

end

Page 156: Therapeutic refactoring

class XYZFile ... def truncated_title truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length truncated_title[0..(truncate_to)] end

end

Page 157: Therapeutic refactoring

target.title.gsub(/[^\[a-z\]]/i, '').

downcase

Page 158: Therapeutic refactoring

target.title.gsub(/[^\[a-z\]]/i, '').

downcase

Page 159: Therapeutic refactoring

target.title.gsub(/[^\[a-z\]]/i, '').

downcase

Page 160: Therapeutic refactoring

target.title.downcasegsub(/[^\[a-z\]]/, '')

Page 161: Therapeutic refactoring

truncated_title[0..(truncate_to)]

Page 162: Therapeutic refactoring

truncated_title[0..(truncate_to)]

Page 163: Therapeutic refactoring

truncated_title[0..truncate_to]

Page 164: Therapeutic refactoring

truncate_to = length > 9 ? 9 : lengthtruncated_title[0..truncate_to]

Page 165: Therapeutic refactoring

truncate_to = length > 9 ? 9 : length

truncated_title[0..9]

Page 166: Therapeutic refactoring

length = truncated_title.lengthtruncate_to = length > 9 ? 9 : length

truncated_title[0..9]

Page 167: Therapeutic refactoring

length = truncated_title.lengthtruncate_to = length > 9 ? 9 : length

truncated_title[0..9]

Page 168: Therapeutic refactoring

class XYZFile ... def truncated_title truncated_title = target.title.downcase.gsub(/[^\[a-z\]]/, '') truncated_title[0..truncate_to] end

end

Page 169: Therapeutic refactoring

class XYZFile ... def truncated_title truncated_title = target.title.downcase.gsub(/[^\[a-z\]]/, '') truncated_title[0..truncate_to] end

end

Page 170: Therapeutic refactoring

class XYZFile ... def truncated_title target.title.downcase. gsub(/[^\[a-z\]]/, '')[0..9] end

end

Page 171: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def truncated_title...

end

Page 172: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def truncated_title...

end

Page 173: Therapeutic refactoring

class XYZFile ... def name ... filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" ... end

def truncated_title...

end

Page 174: Therapeutic refactoring

class XYZFile ... def name ... filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" ... end

def noise end

def truncated_title...

end

Page 175: Therapeutic refactoring

class XYZFile ... def name ... filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" ... end

def noise Digest::SHA1.hexdigest(rand(10000).to_s)[0,8] end

def truncated_title...

end

Page 176: Therapeutic refactoring

class XYZFile ... def name ... filename << "_#{noise}" ... end

def noise Digest::SHA1.hexdigest(rand(10000).to_s)[0,8] end

def truncated_title...

end

Page 177: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def noise...

def truncated_title...

end

Page 178: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def noise...

def truncated_title...

end

Page 179: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def age "%03d" % (target.age || 0) end

def noise...

def truncated_title...

end

Page 180: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def age...

def noise...

def truncated_title...

end

Page 181: Therapeutic refactoring

class XYZFile ... def name filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def age...

def noise...

def truncated_title...

end

Page 182: Therapeutic refactoring

class XYZFile ... def name filename = "#{publication_day}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def publication_day target.publish_on.strftime("%d") end

def age...

def noise...

def truncated_title...

end

Page 183: Therapeutic refactoring

class XYZFile ... def name filename = "#{publication_day}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def publication_day...

def age...

def noise...

def truncated_title...

end

Page 184: Therapeutic refactoring

class XYZFile ... def name filename = "#{publication_day}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def publication_day...

def age...

def noise...

def truncated_title...

end

Page 185: Therapeutic refactoring

class XYZFile ... def name filename = "#{publication_day}" filename << "#{category}" filename << "#{target.kind.gsub("_", "")}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def category target.xyz_category_prefix end

def publication_day...

def age...

def noise...

def truncated_title...

end

Page 186: Therapeutic refactoring

class XYZFile ... def name filename = "#{publication_day}" filename << "#{category}" filename << "#{target.kind.gsub("_", "")}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def publication_day...

def category...

def age...

def noise...

def truncated_title...

end

Page 187: Therapeutic refactoring

class XYZFile ... def name filename = "#{publication_day}" filename << "#{category}" filename << "#{kind}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def kind target.kind.gsub("_", "") end

def publication_day...

def category...

def age...

def noise...

def truncated_title...

end

Page 188: Therapeutic refactoring

class XYZFile ... def name filename = "#{publication_day}" filename << "#{category}" filename << "#{kind}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def publication_day... def category... def kind... def age... def noise... def truncated_title...

end

Page 189: Therapeutic refactoring

class XYZFile ... def name filename = "#{publication_day}" filename << "#{category}" filename << "#{kind}" filename << "_#{age}" if target.personal? filename << "_#{target.id.to_s}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" return filename end

def publication_day... def category... def kind... def age... def noise... def truncated_title...

end

Page 190: Therapeutic refactoring

filename = "#{publication_day}"

Page 191: Therapeutic refactoring

filename = "#{publication_day}"

Page 192: Therapeutic refactoring

filename = publication_day

Page 193: Therapeutic refactoring

filename << "#{category}"

Page 194: Therapeutic refactoring

filename << category

Page 195: Therapeutic refactoring

filename << "#{kind}"

Page 196: Therapeutic refactoring

filename << kind

Page 197: Therapeutic refactoring

filename << "_#{target.id.to_s}"

Page 198: Therapeutic refactoring

filename << "_#{target.id}"

Page 199: Therapeutic refactoring

return filename

Page 200: Therapeutic refactoring

filename

Page 201: Therapeutic refactoring

class XYZFile ... def name filename = publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" filename end ...end

Page 202: Therapeutic refactoring

http://klesgaver.spreadshirt.no/finn-fem-feil-A8534272

Page 203: Therapeutic refactoring

class XYZFile ... def name filename = publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" filename end ...end

Page 204: Therapeutic refactoring

class XYZFile ... def name filename = publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" filename end ...end

Page 205: Therapeutic refactoring

class XYZFile ... def name filename = publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" filename end ...end

Page 206: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" filename end ...end

Page 207: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" filename end ...end

Page 208: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" filename end ...end

Page 209: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" filename << ".jpg" filename end ...end

Page 210: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 211: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 212: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 213: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << publication_day filename << category filename << kind filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 214: Therapeutic refactoring

class XYZFile ... def name ... filename << publication_day filename << category filename << kind ... end ...end

Page 215: Therapeutic refactoring

class XYZFile ... def name ... filename << publication_day filename << category filename << kind ... end

def prefix [publication_day, category, kind].join end

...end

Page 216: Therapeutic refactoring

class XYZFile ... def name ... filename << prefix ... end

def prefix [publication_day, category, kind].join end

...end

Page 217: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << prefix filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 218: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << prefix filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 219: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 220: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 221: Therapeutic refactoring

class XYZFile ... def name filename = "" filename << prefix filename << age if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 222: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 223: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << "_#{truncated_title}" "#{filename}.jpg" end ...end

Page 224: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << truncated_title "#{filename}.jpg" end ...end

Page 225: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << truncated_title "#{filename.join("_")}.jpg" end ...end

Page 226: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << truncated_title "#{filename.join("_")}.jpg" end

def prefix... def publication_day... def category... def kind... def age... def noise... def truncated_title... ...end

Page 228: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 229: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << truncated_title "#{filename.join("_")}.jpg" end

def prefix... def publication_day... def category... def kind... def age... def noise... def truncated_title... ...end

Page 230: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 231: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << truncated_title "#{filename.join("_")}.jpg" end

def prefix... def publication_day... def category... def kind... def age... def noise... def truncated_title... ...end

Page 232: Therapeutic refactoring

module XYZService

def self.xyz_filename(target) # File format: # [day of month zero-padded][three-letter prefix] \ # _[kind]_[age_if_kind_personal]_[target.id] \ # _[8 random chars]_[10 first chars of title].jpg filename = "#{target.publish_on.strftime("%d")}" filename << "#{target.xyz_category_prefix}" filename << "#{target.kind.gsub("_", "")}" filename << "_%03d" % (target.age || 0) if target.personal? filename << "_#{target.id.to_s}" filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" truncated_title = target.title.gsub(/[^\[a-z\]]/i, '').downcase length = truncated_title.length truncate_to = length > 9 ? 9 : length filename << "_#{truncated_title[0..(truncate_to)]}" filename << ".jpg" return filename end

end

Page 233: Therapeutic refactoring

class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << truncated_title "#{filename.join("_")}.jpg" end

def prefix... def publication_day... def category... def kind... def age... def noise... def truncated_title... ...end

Page 234: Therapeutic refactoring

(the ending)

Codejunk

Page 235: Therapeutic refactoring

Illustration from Chartjunk by Viveka Weileyhttp://chartjunk.karmanaut.com/?p=8

Page 236: Therapeutic refactoring

Illustration from Chartjunk by Viveka Weileyhttp://chartjunk.karmanaut.com/test-pattern-retuned/

Page 237: Therapeutic refactoring

Top 10

Page 238: Therapeutic refactoring

Lousy Comments

#10

Page 239: Therapeutic refactoring

module Codejunk

# States the obvious def state_the_obvious "whatever" end

end

Page 240: Therapeutic refactoring

module Codejunk

# Takes modulus 100 def say_it_again(number) number % 100 end

end

Page 241: Therapeutic refactoring

module Codejunk

# Subtracts def incorrect_comment 1 + 1 end

end

Page 242: Therapeutic refactoring

module Codejunk

# add def fuzzy_comment 1 + 1 end

end

Page 243: Therapeutic refactoring

module Codejunk

# ad too numbers def bad_comment 1 + 2 end

end

Page 244: Therapeutic refactoring

Unnecessary Explicit Return

#9

Page 245: Therapeutic refactoring

module Codejunk

def spurious_return return "i before e except after c" end

end

Page 246: Therapeutic refactoring

Trailing Whitespace

#8

Page 247: Therapeutic refactoring

module Codejunk def a_method 'Use your words' end end

...................

.................

......

..

..

.

..

Page 248: Therapeutic refactoring

Commented-Out Code

#7

Page 249: Therapeutic refactoring

module Codejunk

def tweaked_logic(wday) # ((7 - wday) % 7) * 1.day (7 - wday) % 7 end

end

Page 250: Therapeutic refactoring

module Codejunk

def tweaked_logic(wday) if false ((7 - wday) % 7) * 1.day end (7 - wday) % 7 end

end

Page 251: Therapeutic refactoring

Needless Parentheses

#6

Page 252: Therapeutic refactoring

module Codejunk

def spurious_parentheses() junk() end

end

Page 253: Therapeutic refactoring

module Codejunk

def more_spurious_parentheses (0..(one_method_call)).to_a end

def one_method_call (10 - rand(10)) end

end

Page 254: Therapeutic refactoring

Explicit Default Parameters

#5

Page 255: Therapeutic refactoring

module Codejunk

def spurious_arguments [1, 2, 3].join('') end

end

Page 256: Therapeutic refactoring

Unnecessary Requires

#4

Page 257: Therapeutic refactoring

require 'active_support/all'

# Nothing uses active supportmodule Codejunk ...end

Page 258: Therapeutic refactoring

Stringifying Strings

#3

Page 259: Therapeutic refactoring

module Codejunk

def spurious_string_interpolation "#{thing}" end

def thing "a string" end

end

Page 260: Therapeutic refactoring

Too Much Hard Work

#2

Page 261: Therapeutic refactoring

module Codejunk

def spurious_stringification "I am #{age.to_s} years old" end

def age rand(25) + 15 end

end

Page 262: Therapeutic refactoring

module Codejunk

def spurious_transformations [1, 2, 3].map(&:to_s).join end

end

Page 263: Therapeutic refactoring

module Codejunk

def spurious_complexity s = rand(2) == 0 ? "abcde" : "abc" cutoff = s.length > 4 ? 4 : s.length s[0..cutoff] end

end

Page 264: Therapeutic refactoring

module Codejunk

def spurious_hard_work s = "I <3 Magic!" s.gsub(/[^a-z]/i, '').downcase end

end

Page 265: Therapeutic refactoring

Duplicated Tests

#1

Page 266: Therapeutic refactoring

describe Codejunk do

subject { stub.extend(Codejunk) }

it "gets rid of spaces" do subject.sanitize(" o m g ").should eq('omg') end

it "gets rid of funky characters" do subject.sanitize("omg^%#=}{?_").should eq('omg') end

it "gets rid of numbers" do subject.sanitize("omg123").should eq('omg') end

it "downcases everything" do subject.sanitize("OMG").should eq('omg') end

end

Page 267: Therapeutic refactoring

Combine All The Codejunk

#0

Page 268: Therapeutic refactoring

module Codejunk

def junk # Subtracts s = rand(2) == 0 ? "abcde" : "abc" cutoff = s.length > 4 ? 4 : s.length s = s[0..cutoff] s << "#{spurious_string_interpolation()}" s << "I am #{age.to_s} years old, and " s << "I <3 Magic!".gsub(/[^a-z]/i, '').downcase s << "#{(0..(one_method_call)).map(&:to_s).join('')}" return s end

end

Page 269: Therapeutic refactoring

github.com/kytrinyx /therapeutic-refactoring

Page 270: Therapeutic refactoring

github.com/kytrinyx /therapeutic-refactoring

Page 271: Therapeutic refactoring

github.com/kytrinyx /therapeutic-refactoring@[email protected]

Page 272: Therapeutic refactoring

(the moral)

Therapy

Page 273: Therapeutic refactoring
Page 274: Therapeutic refactoring

I❤refactoring

Page 275: Therapeutic refactoring

Working Memory

Science!

Page 276: Therapeutic refactoring

Problem-Solving Strategies

Science!

Page 277: Therapeutic refactoring

Worry & Panic

Science!

Page 278: Therapeutic refactoring

makes you smarter!

Refactoring

Page 279: Therapeutic refactoring

Exobrain

Page 280: Therapeutic refactoring

counteracts panic

Exobrain

Page 281: Therapeutic refactoring

makes you happier!

Refactoring

Page 282: Therapeutic refactoring

Fast Tests

Page 283: Therapeutic refactoring

are awesome

Fast Tests

Page 284: Therapeutic refactoring

Happiness

Page 285: Therapeutic refactoring

leads to good design

Happiness

Page 286: Therapeutic refactoring

Illustration from God of Cake by Allie Broshhttp://hyperboleandahalf.blogspot.no/2010/10/god-of-cake.html

Page 287: Therapeutic refactoring

Katrina [email protected]/kytrinyx/therapeutic-refactoring

KTHXBYE