SlideShare a Scribd company logo
1 of 287
Download to read offline
Therapeutic
   Refactoring
Katrina Owen
@kytrinyx
github.com/kytrinyx/therapeutic-refactoring
Illustration from Am Adult by Allie Brosh
http://hyperboleandahalf.blogspot.com/2010/03/am-adult.html
Photo: Johanna Owen 2011
Illustration from U B Hatin’ by Allie Brosh
http://hyperboleandahalf.blogspot.com/2010/03/u-b-hatin.html
I❤
refactoring
Illustration from There’s a Lesson in Here Somewhere, I Think by Allie Brosh
http://hyperboleandahalf.blogspot.com/2010/01/theres-lesson-in-here-somewhere-i-
                                                                          think.html
Illustration from There’s a Lesson in Here Somewhere, I Think by Allie Brosh
http://hyperboleandahalf.blogspot.com/2010/01/theres-lesson-in-here-somewhere-i-
                                                                          think.html
refactoring
   is not
rehacktoring
A Story
Inspired by true events
Illustration from The Scariest Story by Allie Brosh
http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
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
Illustration from The Scariest Story by Allie Brosh
http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
Illustration from The Scariest Story by Allie Brosh
http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
Illustration from The Scariest Story by Allie Brosh
http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
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
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
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
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
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
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
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
Tests
(the first middle)
describe XYZService do
end
describe XYZService do

  it "works" do
  end

end
describe XYZService do

  subject { XYZService.xyz_filename(stub) }

  it "works" do
  end

end
describe XYZService do

  subject { XYZService.xyz_filename(stub) }

  it "works" do
  end

end
describe XYZService do

  subject { XYZService.xyz_filename(stub) }

  it "works" do
  end

end
describe XYZService do

  subject { XYZService.xyz_filename(stub) }

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

end
subject.should eq
 "something"
subject.should eq
  "whatever"
subject.should eq
   "freddy"
subject.should eq
 "something"
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'
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'
Stub received unexpected message



:publish_on
          with (no args)
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'
# ./xyz_service.rb:6
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
target.publish_on.
  strftime("%d")
target.publish_on.
  strftime("%d")
target.publish_on.
  strftime("%d")
describe XYZService do

  subject { XYZService.xyz_filename(stub) }

  it "works" do
  end

end
describe XYZService do

  subject { XYZService.xyz_filename(target) }

  it "works" do
  end

end
describe XYZService do

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

  subject { XYZService.xyz_filename(target) }

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

end
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
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
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
Stub received unexpected message


:xyz_category_prefix
            with (no args)
...


  :xyz_category_prefix => ?,
...
...


  :xyz_category_prefix => 'abc',
...
Stub received unexpected message



       :kind
         with (no args)
...

  :kind => ?

...
...

  :kind => 'unicorn'

...
Stub received unexpected message



:personal?
         with (no args)
...

  :personal? => ?

...
...

  :personal? => false

...
Stub received unexpected message



          :id
         with (no args)
...

      :id => ?

...
...

      :id => 1337

...
Stub received unexpected message



     :title
         with (no args)
...

  :title => ?

...
...

  :title => 'magic & superglue'

...
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)>
Failures:

 1) XYZService works

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




              #WIN
      expected: "something"

            got: "14abcunicorn_42_3f4894ca_magicsuper.jpg"

      (compared using ==)

    # ./xyz_file_spec.rb:18:in `block (2 levels) in
    <top (required)>
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
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)>
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)>
"14abcunicorn_1337_3f4894ca_magicsuper.jpg"
14abcunicorn
_1337_3f4894ca_
magicsuper.jpg
subject.should eq
"14abcunicorn_1337_3f4894ca_magicsuper.jpg"
expected
"14abcunicorn_1337_3f4894ca_magicsuper.jpg"

                   got
"14abcunicorn_1337_59a2b50d_magicsuper.jpg"
expected

"14abcunicorn_1337_3f4894ca      _magicsuper.jpg"



                        got

"14abcunicorn_1337_59a2b50d      _magicsuper.jpg"
subject.should eq
"   14abcunicorn_1337_   3f4894ca   _magicsuper.jpg   "
subject.should match
/   14abcunicorn_1337_   [0-9a-f]{8}   _magicsuper.jpg   /
.
Finished in 0.00073 seconds
1 example, 0 failures
.


     #WIN
Finished in 0.00073 seconds
1 example, 0 failures
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
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
Illustration from The Scariest Story by Allie Brosh
http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
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
target.publish_on.
  strftime("%d")
:publish_on => Date.new(2012, 3, 14)
:publish_on => Date.new(2012, 2, 7)
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
target.kind.gsub("_", "")
:kind => 'unicorn'
:kind => 'magic_unicorn'
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
target.title.
gsub(/[^[a-z]]/i, '').
        downcase
:title => 'magic & superglue'
:title => 'I <3 Sparkles!!1!'
Illustration from Bycicle by Allie Brosh
http://hyperboleandahalf.blogspot.no/2010/07/bicycle.html
target.title.
gsub(/[^[a-z]]/i, '').
        downcase
target.title.
gsub(/[^[a-z]]/i, '').
        downcase
it "works" { ... }
it "leaves square brackets???"
it "leaves square brackets???" do
  target.stub(:title => 'i[sparkle]s')
end
expected

"07abcmagicunicorn_1337_f3b6d325_i[sparkle]     .jpg"



                               to match

/07abcmagicunicorn_1337_[0-9a-z]{8}_isparkles.jpg/
it "works"{ ... }
it "leaves square brackets"{   ... }
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
"_%03d" % (target.age || 0)
if target.personal?
"_%03d" % (target.age || 0)
if target.personal?
it "works" { ... }
it "leaves square brackets"{   ... }
it "personalizes"
it "personalizes" do
  target.stub(:personal? => true)
end
Stub received unexpected message



        :age
         with (no args)
it "personalizes" do
  target.stub(:personal? => true)
  target.stub(:age? => 42)
end
"_%03d" % (target.age || 0)
if target.personal?
"_%03d" % (target.age || 0)
if target.personal?
it   "works"{ ... }
it   "leaves square brackets"{   ... }
it   "personalizes"{ ... }
it   "handles nil age"
it "handles nil age" do
  target.stub(:personal? => true)
  target.stub(:age? => nil)
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
length > 9 ? 9 : length
:title => 'I <3 Sparkles!!1!'
:title => 'I <3 SPARKLY Sparkles!!1!'
it   "works" { ... }
it   "leaves square brackets"    { ... }
it   "personalizes" { ... }
it   "handles nil age" { ... }
it   "handles short titles"
it "handles short titles" do
  target.stub(:title => ‘O HAI’)
end
.....
Finished in 0.00386 seconds
5 examples, 0 failures
.....


        #WIN
Finished in 0.00386 seconds
5 examples, 0 failures
Illustration from This is Why I’ll Never be an Adult by Allie Brosh
http://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html
Refactoring
 (the second middle)
Refactoring
   replace method
 with method object
class XYZFile
end
class XYZFile

  def initialize(target)
  end

end
class XYZFile

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

end
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
class XYZFile

  ...

  def self.xyz_filename(target)
    ...
  end

end
class XYZFile

  ...

  def xyz_filename(target)
    ...
  end

end
class XYZFile

  ...

  def name(target)
    ...
  end

end
class XYZFile

  ...

  def name
    ...
  end

end
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
module XYZService

  def self.xyz_filename(target)

  end

end
require_relative './xyz_file'

module XYZService

  def self.xyz_filename(target)

  end

end
require_relative './xyz_file'

module XYZService

  def self.xyz_filename(target)
    XYZFile.new
  end

end
require_relative './xyz_file'

module XYZService

  def self.xyz_filename(target)
    XYZFile.new(target)
  end

end
require_relative './xyz_file'

module XYZService

  def self.xyz_filename(target)
    XYZFile.new(target)
               (target).name
  end

end
.....
Finished in 0.00398 seconds
5 examples, 0 failures
.....


        #WIN
Finished in 0.00398 seconds
5 examples, 0 failures
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
class XYZFile
  ...
  def name
    ...
    filename << "_#{truncated_title}"
    ...
  end

  def truncated_title...

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

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

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

end
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
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
class XYZFile
  ...
  def name
    ...
    filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}"
    ...
  end

  def truncated_title...

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

  def noise
  end

  def truncated_title...

end
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
class XYZFile
  ...
  def name
    ...
    filename << "_#{noise}"
    ...
  end

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

  def truncated_title...

end
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
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
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
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
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
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
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
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
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...
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
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...
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
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
filename = "#{publication_day}"
filename = "#{publication_day}"
filename = publication_day
filename << "#{category}"
filename << category
filename << "#{kind}"
filename << kind
filename << "_#{target.id.to_s}"
filename << "_#{target.id}"
return filename
filename
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
http://klesgaver.spreadshirt.no/finn-fem-feil-A8534272
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
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
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
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
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
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
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
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
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
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
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
class XYZFile
  ...
  def name
    ...
    filename << publication_day
    filename << category
    filename << kind
    ...
  end
  ...
end
class XYZFile
  ...
  def name
    ...
    filename << publication_day
    filename << category
    filename << kind
    ...
  end

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

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

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

  ...
end
class XYZFile
  ...
  def name
    filename = ""
    filename << prefix
    filename << "_#{age}" if target.personal?
    filename << "_#{target.id}"
    filename << "_#{noise}"
    filename << "_#{truncated_title}"
    "#{filename}.jpg"
  end
  ...
end
class XYZFile
  ...
  def name
    filename = ""
    filename << prefix
    filename << "_#{age}" if target.personal?
    filename << "_#{target.id}"
    filename << "_#{noise}"
    filename << "_#{truncated_title}"
    "#{filename}.jpg"
  end
  ...
end
class XYZFile
  ...
  def name
    filename = []
    filename << prefix
    filename << "_#{age}" if target.personal?
    filename << "_#{target.id}"
    filename << "_#{noise}"
    filename << "_#{truncated_title}"
    "#{filename}.jpg"
  end
  ...
end
class XYZFile
  ...
  def name
    filename = []
    filename << prefix
    filename << "_#{age}" if target.personal?
    filename << "_#{target.id}"
    filename << "_#{noise}"
    filename << "_#{truncated_title}"
    "#{filename}.jpg"
  end
  ...
end
class XYZFile
  ...
  def name
    filename = ""
    filename << prefix
    filename << age if target.personal?
    filename << "_#{target.id}"
    filename << "_#{noise}"
    filename << "_#{truncated_title}"
    "#{filename}.jpg"
  end
  ...
end
class XYZFile
  ...
  def name
    filename = []
    filename << prefix
    filename << age if target.personal?
    filename << target.id
    filename << "_#{noise}"
    filename << "_#{truncated_title}"
    "#{filename}.jpg"
  end
  ...
end
class XYZFile
  ...
  def name
    filename = []
    filename << prefix
    filename << age if target.personal?
    filename << target.id
    filename << noise
    filename << "_#{truncated_title}"
    "#{filename}.jpg"
  end
  ...
end
class XYZFile
  ...
  def name
    filename = []
    filename << prefix
    filename << age if target.personal?
    filename << target.id
    filename << noise
    filename << truncated_title
    "#{filename}.jpg"
  end
  ...
end
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
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
Illustration from About by Allie Brosh
http://hyperboleandahalf.blogspot.com/p/about.html
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
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
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
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
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
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
Codejunk
 (the ending)
Illustration from Chartjunk by Viveka Weiley
          http://chartjunk.karmanaut.com/?p=8
Illustration from Chartjunk by Viveka Weiley
http://chartjunk.karmanaut.com/test-pattern-retuned/
Top 10
#10
Lousy Comments
module Codejunk

  # States the obvious
  def state_the_obvious
    "whatever"
  end

end
module Codejunk

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

end
module Codejunk

  # Subtracts
  def incorrect_comment
    1 + 1
  end

end
module Codejunk

  # add
  def fuzzy_comment
    1 + 1
  end

end
module Codejunk

  # ad too numbers
  def bad_comment
    1 + 2
  end

end
#9
Unnecessary Explicit Return
module Codejunk

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

end
#8
Trailing Whitespace
module Codejunk   ......
..
..
   def a_method .
     'Use your words' ................
   end ...
..
.................
end
#7
Commented-Out Code
module Codejunk

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

end
module Codejunk

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

end
#6
Needless Parentheses
module Codejunk

  def spurious_parentheses()
    junk()
  end

end
module Codejunk

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

  def one_method_call
    (10 - rand(10))
  end

end
#5
Explicit Default Parameters
module Codejunk

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

end
#4
Unnecessary Requires
require 'active_support/all'

# Nothing uses active support
module Codejunk
  ...
end
#3
Stringifying Strings
module Codejunk

  def spurious_string_interpolation
    "#{thing}"
  end

  def thing
    "a string"
  end

end
#2
Too Much Hard Work
module Codejunk

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

  def age
    rand(25) + 15
  end

end
module Codejunk

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

end
module Codejunk

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

end
module Codejunk

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

end
#1
Duplicated Tests
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
#0
Combine All The Codejunk
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
github.com/kytrinyx
/therapeutic-refactoring
github.com/kytrinyx
/therapeutic-refactoring
github.com/kytrinyx
 /therapeutic-refactoring
@kytrinyx
kytrinyx@gmail.com
Therapy
 (the moral)
I❤
refactoring
Science!
Working Memory
Science!
Problem-Solving Strategies
Science!
 Worry & Panic
Refactoring
 makes you smarter!
Exobrain
Exobrain
counteracts panic
Refactoring
 makes you happier!
Fast Tests
Fast Tests
  are awesome
Happiness
Happiness
leads to good design
Illustration from God of Cake by Allie Brosh
http://hyperboleandahalf.blogspot.no/2010/10/god-of-cake.html
KTHXBYE
Katrina Owen
@kytrinyx
github.com/kytrinyx/therapeutic-refactoring

More Related Content

What's hot

Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsTse-Ching Ho
 
Recent Changes to jQuery's Internals
Recent Changes to jQuery's InternalsRecent Changes to jQuery's Internals
Recent Changes to jQuery's Internalsjeresig
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented ArchitectureLuiz Messias
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In RailsLouie Zhao
 
Getting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, AgainGetting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, AgainDrewAPicture
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 
Devs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingDevs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingFabio Akita
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 
Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blogPierre Sudron
 

What's hot (17)

jQuery
jQueryjQuery
jQuery
 
Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
jQuery
jQueryjQuery
jQuery
 
Laravel
LaravelLaravel
Laravel
 
Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in rails
 
Recent Changes to jQuery's Internals
Recent Changes to jQuery's InternalsRecent Changes to jQuery's Internals
Recent Changes to jQuery's Internals
 
Command-Oriented Architecture
Command-Oriented ArchitectureCommand-Oriented Architecture
Command-Oriented Architecture
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In Rails
 
Jquery 3
Jquery 3Jquery 3
Jquery 3
 
Getting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, AgainGetting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, Again
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Devs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented ProgrammingDevs for Leokz e 7Masters - WTF Oriented Programming
Devs for Leokz e 7Masters - WTF Oriented Programming
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blog
 
Emmet cheat-sheet
Emmet cheat-sheetEmmet cheat-sheet
Emmet cheat-sheet
 

Viewers also liked

Terminal slides
Terminal slidesTerminal slides
Terminal slideskytrinyx
 
Assistive Technology
Assistive TechnologyAssistive Technology
Assistive Technologymtt2258
 
5 power point-templates-for-toastmasters
5 power point-templates-for-toastmasters5 power point-templates-for-toastmasters
5 power point-templates-for-toastmastersBrian Rouley
 

Viewers also liked (6)

Florida Foreclosure Property Fund
Florida Foreclosure Property FundFlorida Foreclosure Property Fund
Florida Foreclosure Property Fund
 
Angles final de curs
Angles final de cursAngles final de curs
Angles final de curs
 
Terminal slides
Terminal slidesTerminal slides
Terminal slides
 
Assistive Technology
Assistive TechnologyAssistive Technology
Assistive Technology
 
Croak.it ppt
Croak.it pptCroak.it ppt
Croak.it ppt
 
5 power point-templates-for-toastmasters
5 power point-templates-for-toastmasters5 power point-templates-for-toastmasters
5 power point-templates-for-toastmasters
 

Similar to Therapeutic refactoring

Using Scala Slick at FortyTwo
Using Scala Slick at FortyTwoUsing Scala Slick at FortyTwo
Using Scala Slick at FortyTwoEishay Smith
 
Making Templatetags Suck Less
Making Templatetags Suck LessMaking Templatetags Suck Less
Making Templatetags Suck LessAlex Gaynor
 
Crowdsourcing with Django
Crowdsourcing with DjangoCrowdsourcing with Django
Crowdsourcing with DjangoSimon Willison
 
Python Ireland Nov 2010 Talk: Unit Testing
Python Ireland Nov 2010 Talk: Unit TestingPython Ireland Nov 2010 Talk: Unit Testing
Python Ireland Nov 2010 Talk: Unit TestingPython Ireland
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaiMasters
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 
Creating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonCreating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonSiddhi
 
Slides python elixir
Slides python elixirSlides python elixir
Slides python elixirAdel Totott
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethodsdreampuf
 
Coffeescript a z
Coffeescript a zCoffeescript a z
Coffeescript a zStarbuildr
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Brian Hogan
 
Detect Negative and Positive sentiment in user reviews using python word2vec ...
Detect Negative and Positive sentiment in user reviews using python word2vec ...Detect Negative and Positive sentiment in user reviews using python word2vec ...
Detect Negative and Positive sentiment in user reviews using python word2vec ...Mamoon Ismail Khalid
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 

Similar to Therapeutic refactoring (20)

Using Scala Slick at FortyTwo
Using Scala Slick at FortyTwoUsing Scala Slick at FortyTwo
Using Scala Slick at FortyTwo
 
Making Templatetags Suck Less
Making Templatetags Suck LessMaking Templatetags Suck Less
Making Templatetags Suck Less
 
Crowdsourcing with Django
Crowdsourcing with DjangoCrowdsourcing with Django
Crowdsourcing with Django
 
Python Ireland Nov 2010 Talk: Unit Testing
Python Ireland Nov 2010 Talk: Unit TestingPython Ireland Nov 2010 Talk: Unit Testing
Python Ireland Nov 2010 Talk: Unit Testing
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio Akita
 
Elastic tire demo
Elastic tire demoElastic tire demo
Elastic tire demo
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
Creating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonCreating Domain Specific Languages in Python
Creating Domain Specific Languages in Python
 
Slides python elixir
Slides python elixirSlides python elixir
Slides python elixir
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Ggplot2 v3
Ggplot2 v3Ggplot2 v3
Ggplot2 v3
 
Coffeescript a z
Coffeescript a zCoffeescript a z
Coffeescript a z
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
D3 data visualization
D3 data visualizationD3 data visualization
D3 data visualization
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7
 
Detect Negative and Positive sentiment in user reviews using python word2vec ...
Detect Negative and Positive sentiment in user reviews using python word2vec ...Detect Negative and Positive sentiment in user reviews using python word2vec ...
Detect Negative and Positive sentiment in user reviews using python word2vec ...
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
R data interfaces
R data interfacesR data interfaces
R data interfaces
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 

Recently uploaded (20)

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 

Therapeutic refactoring

  • 1. Therapeutic Refactoring Katrina Owen @kytrinyx github.com/kytrinyx/therapeutic-refactoring
  • 2. Illustration from Am Adult by Allie Brosh http://hyperboleandahalf.blogspot.com/2010/03/am-adult.html
  • 4. Illustration from U B Hatin’ by Allie Brosh http://hyperboleandahalf.blogspot.com/2010/03/u-b-hatin.html
  • 6. Illustration from There’s a Lesson in Here Somewhere, I Think by Allie Brosh http://hyperboleandahalf.blogspot.com/2010/01/theres-lesson-in-here-somewhere-i- think.html
  • 7. Illustration from There’s a Lesson in Here Somewhere, I Think by Allie Brosh http://hyperboleandahalf.blogspot.com/2010/01/theres-lesson-in-here-somewhere-i- think.html
  • 8. refactoring is not rehacktoring
  • 9. A Story Inspired by true events
  • 10. Illustration from The Scariest Story by Allie Brosh http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
  • 11. 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
  • 12. Illustration from The Scariest Story by Allie Brosh http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
  • 13. Illustration from The Scariest Story by Allie Brosh http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
  • 14. Illustration from The Scariest Story by Allie Brosh http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
  • 15. 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
  • 16. 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
  • 17. 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
  • 18. 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
  • 19. 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
  • 20. 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
  • 21. 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
  • 24. describe XYZService do it "works" do end end
  • 25. describe XYZService do subject { XYZService.xyz_filename(stub) } it "works" do end end
  • 26. describe XYZService do subject { XYZService.xyz_filename(stub) } it "works" do end end
  • 27. describe XYZService do subject { XYZService.xyz_filename(stub) } it "works" do end end
  • 28. describe XYZService do subject { XYZService.xyz_filename(stub) } it "works" do subject.should eq("something") end end
  • 30. subject.should eq "whatever"
  • 31. subject.should eq "freddy"
  • 33. 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'
  • 34. 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'
  • 35. Stub received unexpected message :publish_on with (no args)
  • 36. 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'
  • 38. 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
  • 42. describe XYZService do subject { XYZService.xyz_filename(stub) } it "works" do end end
  • 43. describe XYZService do subject { XYZService.xyz_filename(target) } it "works" do end end
  • 44. describe XYZService do let(:target) do stub(:target) end subject { XYZService.xyz_filename(target) } it "works" do subject.should eq("something") end end
  • 45. 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
  • 46. 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
  • 47. 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
  • 48. Stub received unexpected message :xyz_category_prefix with (no args)
  • 50. ... :xyz_category_prefix => 'abc', ...
  • 51. Stub received unexpected message :kind with (no args)
  • 52. ... :kind => ? ...
  • 53. ... :kind => 'unicorn' ...
  • 54. Stub received unexpected message :personal? with (no args)
  • 55. ... :personal? => ? ...
  • 56. ... :personal? => false ...
  • 57. Stub received unexpected message :id with (no args)
  • 58. ... :id => ? ...
  • 59. ... :id => 1337 ...
  • 60. Stub received unexpected message :title with (no args)
  • 61. ... :title => ? ...
  • 62. ... :title => 'magic & superglue' ...
  • 63. 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)>
  • 64. Failures: 1) XYZService works Failure/Error: subject.should eq("something") #WIN expected: "something" got: "14abcunicorn_42_3f4894ca_magicsuper.jpg" (compared using ==) # ./xyz_file_spec.rb:18:in `block (2 levels) in <top (required)>
  • 65. 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
  • 66. 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)>
  • 67. 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)>
  • 71. expected "14abcunicorn_1337_3f4894ca_magicsuper.jpg" got "14abcunicorn_1337_59a2b50d_magicsuper.jpg"
  • 72. expected "14abcunicorn_1337_3f4894ca _magicsuper.jpg" got "14abcunicorn_1337_59a2b50d _magicsuper.jpg"
  • 73. subject.should eq " 14abcunicorn_1337_ 3f4894ca _magicsuper.jpg "
  • 74. subject.should match / 14abcunicorn_1337_ [0-9a-f]{8} _magicsuper.jpg /
  • 75. . Finished in 0.00073 seconds 1 example, 0 failures
  • 76. . #WIN Finished in 0.00073 seconds 1 example, 0 failures
  • 77. 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
  • 78. 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
  • 79. Illustration from The Scariest Story by Allie Brosh http://hyperboleandahalf.blogspot.com/2011/02/scariest-story.html
  • 80. 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
  • 84. 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
  • 88. 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
  • 90. :title => 'magic & superglue'
  • 91. :title => 'I <3 Sparkles!!1!'
  • 92. Illustration from Bycicle by Allie Brosh http://hyperboleandahalf.blogspot.no/2010/07/bicycle.html
  • 95. it "works" { ... } it "leaves square brackets???"
  • 96. it "leaves square brackets???" do target.stub(:title => 'i[sparkle]s') end
  • 97. expected "07abcmagicunicorn_1337_f3b6d325_i[sparkle] .jpg" to match /07abcmagicunicorn_1337_[0-9a-z]{8}_isparkles.jpg/
  • 98. it "works"{ ... } it "leaves square brackets"{ ... }
  • 99. 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
  • 100. "_%03d" % (target.age || 0) if target.personal?
  • 101. "_%03d" % (target.age || 0) if target.personal?
  • 102. it "works" { ... } it "leaves square brackets"{ ... } it "personalizes"
  • 103. it "personalizes" do target.stub(:personal? => true) end
  • 104. Stub received unexpected message :age with (no args)
  • 105. it "personalizes" do target.stub(:personal? => true) target.stub(:age? => 42) end
  • 106. "_%03d" % (target.age || 0) if target.personal?
  • 107. "_%03d" % (target.age || 0) if target.personal?
  • 108. it "works"{ ... } it "leaves square brackets"{ ... } it "personalizes"{ ... } it "handles nil age"
  • 109. it "handles nil age" do target.stub(:personal? => true) target.stub(:age? => nil) end
  • 110. 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
  • 111. length > 9 ? 9 : length
  • 112. :title => 'I <3 Sparkles!!1!'
  • 113. :title => 'I <3 SPARKLY Sparkles!!1!'
  • 114. it "works" { ... } it "leaves square brackets" { ... } it "personalizes" { ... } it "handles nil age" { ... } it "handles short titles"
  • 115. it "handles short titles" do target.stub(:title => ‘O HAI’) end
  • 116. ..... Finished in 0.00386 seconds 5 examples, 0 failures
  • 117. ..... #WIN Finished in 0.00386 seconds 5 examples, 0 failures
  • 118. Illustration from This is Why I’ll Never be an Adult by Allie Brosh http://hyperboleandahalf.blogspot.com/2010/06/this-is-why-ill-never-be-adult.html
  • 120. Refactoring replace method with method object
  • 122. class XYZFile def initialize(target) end end
  • 123. class XYZFile attr_reader :target def initialize(target) @target = target end end
  • 124. 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
  • 125. class XYZFile ... def self.xyz_filename(target) ... end end
  • 126. class XYZFile ... def xyz_filename(target) ... end end
  • 127. class XYZFile ... def name(target) ... end end
  • 128. class XYZFile ... def name ... end end
  • 129. 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
  • 130. module XYZService def self.xyz_filename(target) end end
  • 131. require_relative './xyz_file' module XYZService def self.xyz_filename(target) end end
  • 132. require_relative './xyz_file' module XYZService def self.xyz_filename(target) XYZFile.new end end
  • 133. require_relative './xyz_file' module XYZService def self.xyz_filename(target) XYZFile.new(target) end end
  • 134. require_relative './xyz_file' module XYZService def self.xyz_filename(target) XYZFile.new(target) (target).name end end
  • 135. ..... Finished in 0.00398 seconds 5 examples, 0 failures
  • 136. ..... #WIN Finished in 0.00398 seconds 5 examples, 0 failures
  • 137. 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
  • 138. 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
  • 139. 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
  • 140. 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
  • 141. 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
  • 142. 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
  • 143. 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
  • 144. 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
  • 145. 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
  • 146. 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
  • 147. 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
  • 148. 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
  • 149. 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
  • 150. 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
  • 151. 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
  • 152. 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
  • 153. class XYZFile ... def name ... filename << "_#{truncated_title}" ... end def truncated_title... end
  • 154. 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
  • 155. 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
  • 156. 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
  • 164. truncate_to = length > 9 ? 9 : length truncated_title[0..truncate_to]
  • 165. truncate_to = length > 9 ? 9 : length truncated_title[0..9]
  • 166. length = truncated_title.length truncate_to = length > 9 ? 9 : length truncated_title[0..9]
  • 167. length = truncated_title.length truncate_to = length > 9 ? 9 : length truncated_title[0..9]
  • 168. class XYZFile ... def truncated_title truncated_title = target.title.downcase.gsub(/[^[a-z]]/, '') truncated_title[0..truncate_to] end end
  • 169. class XYZFile ... def truncated_title truncated_title = target.title.downcase.gsub(/[^[a-z]]/, '') truncated_title[0..truncate_to] end end
  • 170. class XYZFile ... def truncated_title target.title.downcase. gsub(/[^[a-z]]/, '')[0..9] end end
  • 171. 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
  • 172. 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
  • 173. class XYZFile ... def name ... filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" ... end def truncated_title... end
  • 174. class XYZFile ... def name ... filename << "_#{Digest::SHA1.hexdigest(rand(10000).to_s)[0,8]}" ... end def noise end def truncated_title... end
  • 175. 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
  • 176. class XYZFile ... def name ... filename << "_#{noise}" ... end def noise Digest::SHA1.hexdigest(rand(10000).to_s)[0,8] end def truncated_title... end
  • 177. 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
  • 178. 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
  • 179. 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
  • 180. 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
  • 181. 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
  • 182. 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
  • 183. 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
  • 184. 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
  • 185. 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...
  • 186. 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
  • 187. 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...
  • 188. 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
  • 189. 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
  • 201. 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
  • 203. 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
  • 204. 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
  • 205. 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
  • 206. 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
  • 207. 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
  • 208. 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
  • 209. 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
  • 210. 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
  • 211. 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
  • 212. 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
  • 213. 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
  • 214. class XYZFile ... def name ... filename << publication_day filename << category filename << kind ... end ... end
  • 215. class XYZFile ... def name ... filename << publication_day filename << category filename << kind ... end def prefix [publication_day, category, kind].join end ... end
  • 216. class XYZFile ... def name ... filename << prefix ... end def prefix [publication_day, category, kind].join end ... end
  • 217. class XYZFile ... def name filename = "" filename << prefix filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ... end
  • 218. class XYZFile ... def name filename = "" filename << prefix filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ... end
  • 219. class XYZFile ... def name filename = [] filename << prefix filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ... end
  • 220. class XYZFile ... def name filename = [] filename << prefix filename << "_#{age}" if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ... end
  • 221. class XYZFile ... def name filename = "" filename << prefix filename << age if target.personal? filename << "_#{target.id}" filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ... end
  • 222. class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << "_#{noise}" filename << "_#{truncated_title}" "#{filename}.jpg" end ... end
  • 223. class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << "_#{truncated_title}" "#{filename}.jpg" end ... end
  • 224. class XYZFile ... def name filename = [] filename << prefix filename << age if target.personal? filename << target.id filename << noise filename << truncated_title "#{filename}.jpg" end ... end
  • 225. 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
  • 226. 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
  • 227. Illustration from About by Allie Brosh http://hyperboleandahalf.blogspot.com/p/about.html
  • 228. 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
  • 229. 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
  • 230. 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
  • 231. 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
  • 232. 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
  • 233. 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
  • 235. Illustration from Chartjunk by Viveka Weiley http://chartjunk.karmanaut.com/?p=8
  • 236. Illustration from Chartjunk by Viveka Weiley http://chartjunk.karmanaut.com/test-pattern-retuned/
  • 237. Top 10
  • 239. module Codejunk # States the obvious def state_the_obvious "whatever" end end
  • 240. module Codejunk # Takes modulus 100 def say_it_again(number) number % 100 end end
  • 241. module Codejunk # Subtracts def incorrect_comment 1 + 1 end end
  • 242. module Codejunk # add def fuzzy_comment 1 + 1 end end
  • 243. module Codejunk # ad too numbers def bad_comment 1 + 2 end end
  • 245. module Codejunk def spurious_return return "i before e except after c" end end
  • 247. module Codejunk ...... .. .. def a_method . 'Use your words' ................ end ... .. ................. end
  • 249. module Codejunk def tweaked_logic(wday) # ((7 - wday) % 7) * 1.day (7 - wday) % 7 end end
  • 250. module Codejunk def tweaked_logic(wday) if false ((7 - wday) % 7) * 1.day end (7 - wday) % 7 end end
  • 252. module Codejunk def spurious_parentheses() junk() end end
  • 253. module Codejunk def more_spurious_parentheses (0..(one_method_call)).to_a end def one_method_call (10 - rand(10)) end end
  • 255. module Codejunk def spurious_arguments [1, 2, 3].join('') end end
  • 257. require 'active_support/all' # Nothing uses active support module Codejunk ... end
  • 259. module Codejunk def spurious_string_interpolation "#{thing}" end def thing "a string" end end
  • 261. module Codejunk def spurious_stringification "I am #{age.to_s} years old" end def age rand(25) + 15 end end
  • 262. module Codejunk def spurious_transformations [1, 2, 3].map(&:to_s).join end end
  • 263. module Codejunk def spurious_complexity s = rand(2) == 0 ? "abcde" : "abc" cutoff = s.length > 4 ? 4 : s.length s[0..cutoff] end end
  • 264. module Codejunk def spurious_hard_work s = "I <3 Magic!" s.gsub(/[^a-z]/i, '').downcase end end
  • 266. 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
  • 267. #0 Combine All The Codejunk
  • 268. 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
  • 273.
  • 283. Fast Tests are awesome
  • 286. Illustration from God of Cake by Allie Brosh http://hyperboleandahalf.blogspot.no/2010/10/god-of-cake.html