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

Therapeutic refactoring

Embed Size (px)

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

Citation preview

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