Nothing is Something (RailsConf)

Nothing is Something (RailsConf)

Our code is full of hidden assumptions, things that seem like nothing, secrets that we did not name and thus cannot see.

These secrets represent missing concepts and this talk shows you how to expose those concepts with code that is easy to understand, change and extend.

Being explicit about hidden ideas makes your code simpler, your apps clearer and your life better. Even very small ideas matter. Everything, even nothing, is something.

66ad01cf37c098bfdb76906a490e018f?s=128

Sandi Metz

April 16, 2015
Tweet

Transcript

  1. Jan 2015 @sandimetz Sandi Metz Nothing is Something

  2. Jan 2015 @sandimetz

  3. Jan 2015 @sandimetz

  4. Jan 2015 @sandimetz Smalltalk Infected

  5. Jan 2015 @sandimetz 1.to_s  

  6. Jan 2015 @sandimetz 1.to_s   =>  "1"

  7. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)

  8. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"
  9. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"
  10. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1" 1  +  1
  11. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1" 1  +  1   =>  2
  12. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1" 1  +  1   =>  2   1.send(:+,  1)
  13. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1" 1  +  1   =>  2   1.send(:+,  1)   =>  2
  14. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2
  15. Jan 2015 @sandimetz 1.class 1.to_s   =>  "1"   1.send(:to_s)

      =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2
  16. Jan 2015 @sandimetz 1.class   =>  Fixnum 1.to_s   =>

     "1"   1.send(:to_s)   =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2
  17. Jan 2015 @sandimetz Fixnum.instance_methods(false)   =>  [    :to_s,  

     :+,    :-­‐,    :*,    :/,    :==,    :%,    :modulo,  #  etc 1.to_s   =>  "1"   1.send(:to_s)   =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2
  18. Jan 2015 @sandimetz Fixnum.instance_methods(false)   =>  [    :to_s,  

     :+,    :-­‐,    :*,    :/,    :==,    :%,    :modulo,  #  etc 1.to_s   =>  "1"   1.send(:to_s)   =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2
  19. Jan 2015 @sandimetz Fixnum.instance_methods(false)   =>  [    :to_s,  

     :+,    :-­‐,    :*,    :/,    :==,    :%,    :modulo,  #  etc 1.to_s   =>  "1"   1.send(:to_s)   =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2
  20. Jan 2015 @sandimetz Fixnum.instance_methods(false)   =>  [    :to_s,  

     :+,    :-­‐,    :*,    :/,    :==,    :%,    :modulo,  #  etc 1.to_s   =>  "1"   1.send(:to_s)   =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2
  21. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2 1  ==  1
  22. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2 1  ==  1   =>  true
  23. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2   1  ==  1   =>  true
  24. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2   1  ==  1   =>  true true.class
  25. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2   1  ==  1   =>  true true.class   =>  TrueClass
  26. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2   1  ==  1   =>  true   true.class   =>  TrueClass
  27. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2   1  ==  1   =>  true   true.class   =>  TrueClass TrueClass.instance_methods(false)   =>  [    :to_s,      :inspect,      :&,      :|,      :^,      :pretty_print_cycle,      :pretty_print]  
  28. Jan 2015 @sandimetz 1.to_s   =>  "1"   1.send(:to_s)  

    =>  "1"   1  +  1   =>  2   1.send(:+,  1)   =>  2   1  ==  1   =>  true   true.class   =>  TrueClass TrueClass.instance_methods(false)   =>  [    :to_s,      :inspect,      :&,      :|,      :^,      :pretty_print_cycle,      :pretty_print]  
  29. Jan 2015 @sandimetz ‘Special’ syntax for booleans

  30. Jan 2015 @sandimetz Smalltalk keywords true,  false,  nil,  self,  super,

     thisContext
  31. Jan 2015 @sandimetz Smalltalk keywords true,  false,  nil,  self,  super,

     thisContext   Ruby keywords alias  and  BEGIN  begin  break  case  class  def  defined?  do   else  elsif  END  end  ensure  false  for  if  in  module  next  nil   not  or  redo  rescue  retry  return  self  super  then  true   undef  unless  until  when  while  yield
  32. Jan 2015 @sandimetz Smalltalk keywords true,  false,  nil,  self,  super,

     thisContext   Ruby keywords alias  and  BEGIN  begin  break  case  class  def  defined?  do   else  elsif  END  end  ensure  false  for  if  in  module  next  nil   not  or  redo  rescue  retry  return  self  super  then  true   undef  unless  until  when  while  yield
  33. Jan 2015 @sandimetz if  (1  ==  1)      'is

     true'   else      'is  false'   end
  34. Jan 2015 @sandimetz if  (1  ==  1)      'is

     true'   else      'is  false'   end true
  35. Jan 2015 @sandimetz if  (1  ==  1)      'is

     true'   else      'is  false'   end   =>  'is  true' true
  36. Jan 2015 @sandimetz if  (1  ==  1)      code

     to  eval  when  ‘true’   else      code  to  eval  when  ‘false’   end true
  37. Jan 2015 @sandimetz if  (  truthy  )      code

     to  eval  when  ‘truthy’   else      code  to  eval  when  ‘falsey’   end
  38. Jan 2015 @sandimetz if  (some  object  whose  type  I  know)

         code  to  do  some  stuff   else      code  to  do  some  other  stuff   end
  39. Jan 2015 @sandimetz I just want to send a message

    to an object
  40. Jan 2015 @sandimetz

  41. Jan 2015 @sandimetz if

  42. Jan 2015 @sandimetz if is an enabler

  43. Jan 2015 @sandimetz ‘Message sending’ syntax for TrueClass / FalseClass

  44. Jan 2015 @sandimetz class  TrueClass   end

  45. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield      end   end
  46. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end   end
  47. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end
  48. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  49. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  50. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  51. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  52. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  53. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  54. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  55. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}

  56. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}

  57. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"} true

  58. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"} class

     TrueClass      def  if_true          yield          self      end      #  …   end true
  59. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"} class

     TrueClass      def  if_true          yield          self      end      #  …   end
  60. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"} class

     TrueClass      def  if_true          yield          self      end      #  …   end
  61. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block" class  TrueClass      def  if_true          yield          self      end      #  …   end
  62. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"} class  TrueClass      def  if_true          yield          self      end      #  …   end
  63. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"} class  TrueClass      def  if_true          yield          self      end      def  if_false          self      end   end
  64. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored class  TrueClass      def  if_true          yield          self      end      def  if_false          self      end   end
  65. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_true  {puts  "evaluated  block"}
  66. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_true  {puts  "evaluated  block"}
  67. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_true  {puts  "evaluated  block"} false
  68. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_true  {puts  "evaluated  block"} false class  FalseClass    def  if_true          self      end      def  if_false          yield          self      end   end
  69. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_true  {puts  "evaluated  block"} class  FalseClass    def  if_true          self      end      def  if_false          yield          self      end   end
  70. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_true  {puts  "evaluated  block"}   #  block  is  ignored class  FalseClass    def  if_true          self      end      def  if_false          yield          self      end   end
  71. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_true  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_false  {puts  "evaluated  block"} class  FalseClass    def  if_true          self      end      def  if_false          yield          self      end   end
  72. Jan 2015 @sandimetz (1  ==  1).if_true  {puts  "evaluated  block"}  

    "evaluated  block"   (1  ==  1).if_false  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_true  {puts  "evaluated  block"}   #  block  is  ignored   (1  ==  2).if_false  {puts  "evaluated  block"}   "evaluated  block" class  FalseClass    def  if_true          self      end      def  if_false          yield          self      end   end
  73. Jan 2015 @sandimetz ‘Message sending’ syntax for truthy/falsey

  74. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  75. Jan 2015 @sandimetz class  TrueClass      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  76. Jan 2015 @sandimetz class  Object      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end
  77. Jan 2015 @sandimetz class  Object      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end class  NilClass      def  if_true          self      end            def  if_false          yield          self      end   end
  78. Jan 2015 @sandimetz class  Object      def  if_true  

           yield          self      end      def  if_false          self      end   end class  FalseClass      def  if_true          self      end            def  if_false          yield          self      end   end class  NilClass      def  if_true          self      end            def  if_false          yield          self      end   end * Shamelessly swiped from http://yehudakatz.com/2009/10/04/emulating-smalltalks-conditionals-in-ruby/
  79. Jan 2015 @sandimetz    (1  ==  1).if_true    {puts  "evaluated

     block"}
  80. Jan 2015 @sandimetz

  81. Jan 2015 @sandimetz "anything".if_true    {puts  "evaluated  block"}

  82. Jan 2015 @sandimetz "anything".if_true    {puts  "evaluated  block"} "evaluated  block"

  83. Jan 2015 @sandimetz "anything".if_true    {puts  "evaluated  block"}   "evaluated

     block"   "anything".if_false  {puts  "evaluated  block"}
  84. Jan 2015 @sandimetz "anything".if_true    {puts  "evaluated  block"}   "evaluated

     block"   "anything".if_false  {puts  "evaluated  block"}   #  block  is  ignored
  85. Jan 2015 @sandimetz "anything".if_true    {puts  "evaluated  block"}   "evaluated

     block"   "anything".if_false  {puts  "evaluated  block"}   #  block  is  ignored   nil.if_true                  {puts  "evaluated  block"}
  86. Jan 2015 @sandimetz "anything".if_true    {puts  "evaluated  block"}   "evaluated

     block"   "anything".if_false  {puts  "evaluated  block"}   #  block  is  ignored   nil.if_true                  {puts  "evaluated  block"}   #  block  is  ignored
  87. Jan 2015 @sandimetz "anything".if_true    {puts  "evaluated  block"}   "evaluated

     block"   "anything".if_false  {puts  "evaluated  block"}   #  block  is  ignored   nil.if_true                  {puts  "evaluated  block"}   #  block  is  ignored   nil.if_false                {puts  "evaluated  block"}
  88. Jan 2015 @sandimetz "anything".if_true    {puts  "evaluated  block"}   "evaluated

     block"   "anything".if_false  {puts  "evaluated  block"}   #  block  is  ignored   nil.if_true                  {puts  "evaluated  block"}   #  block  is  ignored   nil.if_false                {puts  "evaluated  block"}   "evaluated  block"
  89. Jan 2015 @sandimetz if  (1  ==  1)      puts

     'is  true'   else      puts  'is  false'   end   =>  'is  true'
  90. Jan 2015 @sandimetz (1  ==  1).      if_true  {puts

     'is  true'}.      if_false  {puts  'is  false’}   =>  'is  true' if  (1  ==  1)      puts  'is  true'   else      puts  'is  false'   end   =>  'is  true'
  91. Jan 2015 @sandimetz if  (1  ==  2)      puts

     'is  true'   else      puts  'is  false'   end   =>  'is  false' (1  ==  1).      if_true  {puts  'is  true'}.      if_false  {puts  'is  false’}   =>  'is  true' if  (1  ==  1)      puts  'is  true'   else      puts  'is  false'   end   =>  'is  true'
  92. Jan 2015 @sandimetz if  (1  ==  2)      puts

     'is  true'   else      puts  'is  false'   end   =>  'is  false' (1  ==  1).      if_true  {puts  'is  true'}.      if_false  {puts  'is  false’}   =>  'is  true' if  (1  ==  1)      puts  'is  true'   else      puts  'is  false'   end   =>  'is  true' (1  ==  2).      if_true  {puts  'is  true'}.      if_false  {puts  'is  false’}   =>  'is  false'
  93. Jan 2015 @sandimetz I don't want to change Ruby

  94. Jan 2015 @sandimetz I want to change you

  95. Jan 2015 @sandimetz What if there were no 'if' ?

  96. Jan 2015 @sandimetz Smalltalk Infected

  97. Jan 2015 @sandimetz Smalltalk Infected

  98. Jan 2015 @sandimetz Smalltalk Infected Condition Averse

  99. Jan 2015 @sandimetz Animal.find('pig')   =>  #<Animal:0x007f94b28b0030  @name="pig">

  100. Jan 2015 @sandimetz Animal.find('pig')   =>  #<Animal:0x007f94b28b0030  @name="pig">   Animal.find('')

      =>  nil
  101. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']

  102. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}
  103. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]
  104. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.name}   =>  'pig'        NoMethodError:  undefined  method  `name'  for  nil:NilClass
  105. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.name}   =>  'pig'        NoMethodError:  undefined  method  `name'  for  nil:NilClass
  106. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.name}   =>  'pig'        NoMethodError:  undefined  method  `name'  for  nil:NilClass
  107. Jan 2015 @sandimetz Sometimes nil is nothing

  108. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:  @name="pig">,              nil,              #<Animal:  @name="sheep">]
  109. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:  @name="pig">,              nil,              #<Animal:  @name="sheep">]   animals.compact   =>  [#<Animal:  @name="pig">,            #<Animal:  @name="sheep">]
  110. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:  @name="pig">,              nil,              #<Animal:  @name="sheep">]   animals.compact   =>  [#<Animal:  @name="pig">,              #<Animal:  @name="sheep">]   animals.each  {|animal|puts  animal.name}   =>  'pig'          'sheep'
  111. Jan 2015 @sandimetz

  112. Jan 2015 @sandimetz But if you send it a message

  113. Jan 2015 @sandimetz But if you send it a message

    nil is something
  114. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.name}   =>  'pig'        NoMethodError:  undefined  method  `name'  for  nil:NilClass
  115. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.name}   =>  'pig'        NoMethodError:  undefined  method  `name'  for  nil:NilClass
  116. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.nil?  ?  'no  animal'  :  animal.name}   =>  'pig'          'no  animal'        'sheep'
  117. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.nil?  ?  'no  animal'  :  animal.name}   =>  'pig'          'no  animal'        'sheep'
  118. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.nil?  ?  'no  animal'  :  animal.name}   =>  'pig'          'no  animal'        'sheep'
  119. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.nil?  ?  'no  animal'  :  animal.name}   =>  'pig'          'no  animal'        'sheep'
  120. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.nil?  ?  'no  animal'  :  animal.name}   =>  'pig'          'no  animal'        'sheep'
  121. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.nil?  ?  'no  animal'  :  animal.name}   =>  'pig'          'no  animal'        'sheep'
  122. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|      puts  animal  &&  animal.name  }   =>  'pig'          empty  string        'sheep'
  123. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|      puts  animal  &&  animal.name  }   =>  'pig'          empty  string        'sheep'
  124. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|      puts  animal  &&  animal.name  }   =>  'pig'          empty  string        'sheep'
  125. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|      puts  animal  &&  animal.name  }   =>  'pig'          empty  string        'sheep'
  126. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|      puts  animal  &&  animal.name  }   =>  'pig'          empty  string        'sheep'
  127. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|      puts  animal  &&  animal.name  }   =>  'pig'          empty  string        'sheep'
  128. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.try(:name)}   =>  'pig'          empty  string        'sheep'
  129. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.try(:name)}   =>  'pig'          empty  string        'sheep'
  130. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.try(:name)}   =>  'pig'          empty  string        'sheep'
  131. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:0x007f94b290ae90  @name="pig">,              nil,              #<Animal:0x007f94b290ae18  @name="sheep">]   animals.each  {|animal|        puts  animal.try(:name)}   =>  'pig'          empty  string        'sheep'
  132. Jan 2015 @sandimetz puts  animal.try(:name)   puts  animal.nil?  ?  ''

     :  animal.name   puts  animal  ==  nil  ?  ''  :  animal.name   puts  animal.is_a?(NilClass)  ?  ''  :  animal.name
  133. Jan 2015 @sandimetz puts  animal.try(:name)   puts  animal.nil?  ?  ''

     :  animal.name   puts  animal  ==  nil  ?  ''  :  animal.name   puts  animal.is_a?(NilClass)  ?  ''  :  animal.name
  134. Jan 2015 @sandimetz puts  animal.try(:name)   puts  animal.nil?  ?  ''

     :  animal.name   puts  animal  ==  nil  ?  ''  :  animal.name   puts  animal.is_a?(NilClass)  ?  ''  :  animal.name
  135. Jan 2015 @sandimetz puts  animal.try(:name)   puts  animal.nil?  ?  ''

     :  animal.name   puts  animal  ==  nil  ?  ''  :  animal.name   puts  animal.is_a?(NilClass)  ?  ''  :  animal.name
  136. Jan 2015 @sandimetz puts  animal.is_a?(NilClass)  ?  ''  :  animal.name  

    if  animal.is_a?(NilClass)      puts  ''   else      puts  animal.name   end
  137. Jan 2015 @sandimetz puts  animal.is_a?(NilClass)  ?  ''  :  animal.name  

    if  animal.is_a?(NilClass)      puts  ''   else      puts  animal.name   end
  138. Jan 2015 @sandimetz if  animal.is_a?(NilClass)      puts  ''  

    else      puts  animal.name   end
  139. Jan 2015 @sandimetz if  animal.is_a?(NilClass)      puts  ''  

    else      puts  animal.name   end
  140. Jan 2015 @sandimetz if  animal.is_a?(NilClass)      puts  ''  

    else      puts  animal.name   end
  141. Jan 2015 @sandimetz if  (some  object  whose  type  I  know)

         code  to  do  some  stuff   else      code  to  do  some  other  stuff   end if  animal.is_a?(NilClass)      puts  'no  animal'   else      puts  animal.name   end
  142. Jan 2015 @sandimetz if  (some  object  whose  type  I  know)

         code  to  do  some  stuff   else      code  to  do  some  other  stuff   end if  animal.is_a?(NilClass)      puts  'no  animal'   else      puts  animal.name   end
  143. Jan 2015 @sandimetz if  (some  object  whose  type  I  know)

         code  to  do  some  stuff   else      code  to  do  some  other  stuff   end if  animal.is_a?(NilClass)      puts  'no  animal'   else      puts  animal.name   end
  144. Jan 2015 @sandimetz if  (some  object  whose  type  I  know)

         I'll  supply  the  behavior   else      code  to  do  some  other  stuff   end if  animal.is_a?(NilClass)      puts  'no  animal'   else      puts  animal.name   end
  145. Jan 2015 @sandimetz if  (some  object  whose  type  I  know)

         I'll  supply  the  behavior   else      code  to  do  some  other  stuff   end if  animal.is_a?(NilClass)      puts  'no  animal'   else      puts  animal.name   end
  146. Jan 2015 @sandimetz if  (some  object  whose  type  I  know)

         I'll  supply  the  behavior   else      code  to  do  some  other  stuff   end if  animal.is_a?(NilClass)      puts  'no  animal'   else      puts  animal.name   end
  147. Jan 2015 @sandimetz if  animal.is_a?(NilClass)      puts  'no  animal'

      else      puts  animal.name   end if  (some  object  whose  type  I  know)      I'll  supply  the  behavior   else      I'll  send  a  message   end
  148. Jan 2015 @sandimetz

  149. Jan 2015 @sandimetz conditions

  150. Jan 2015 @sandimetz conditions breed

  151. Jan 2015 @sandimetz class  Animal   def  self.find animal  =

     Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name
  152. Jan 2015 @sandimetz class  Animal   def  self.find animal  =

     Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name
  153. Jan 2015 @sandimetz class  Animal   def  self.find ind(id)  

    'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name  Animal.find(id)    ?  'no  animal'  :  animal.name
  154. Jan 2015 @sandimetz class  Animal   def  self.find ind(id)  

    'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name  Animal.find(id)    ?  'no  animal'  :  animal.name find(id)   animal'  :  animal.name d)   imal'  :  animal.name
  155. Jan 2015 @sandimetz class  Animal   def  self.find ind(id)  

    'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name  Animal.find(id)    ?  'no  animal'  :  animal.name find(id)   animal'  :  animal.name d)   imal'  :  animal.name 'no  animal'
  156. Jan 2015 @sandimetz class  Animal   def  self.find ind(id)  

    'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name  Animal.find(id)    ?  'no  animal'  :  animal.name find(id)   animal'  :  animal.name d)   imal'  :  animal.name 'no  animal' 'no  animal'
  157. Jan 2015 @sandimetz class  Animal   def  self.find ind(id)  

    'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name  Animal.find(id)    ?  'no  animal'  :  animal.name find(id)   animal'  :  animal.name d)   imal'  :  animal.name 'no  animal' 'no  animal' 'no  animal'
  158. Jan 2015 @sandimetz class  Animal   def  self.find ind(id)  

    'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name  Animal.find(id)    ?  'no  animal'  :  animal.name find(id)   animal'  :  animal.name d)   imal'  :  animal.name 'no  animal' 'no  animal' 'no  animal' 'no  animal'
  159. Jan 2015 @sandimetz class  Animal   def  self.find ind(id)  

    'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name animal  =  Animal.find(id)   animal.nil?  ?  'no  animal'  :  animal.name  Animal.find(id)    ?  'no  animal'  :  animal.name find(id)   animal'  :  animal.name d)   imal'  :  animal.name 'no  animal' 'no  animal' 'no  animal' 'no  animal' 'no  animal'   !!!!
  160. Jan 2015 @sandimetz Change?

  161. Jan 2015 @sandimetz Shotgun Surgery

  162. Jan 2015 @sandimetz Shotgun Surgery

  163. Jan 2015 @sandimetz Smalltalk Infected Condition Averse

  164. Jan 2015 @sandimetz Smalltalk Infected Condition Averse Message Centric

  165. Jan 2015 @sandimetz if  animal.is_a?(NilClass)      puts  'no  animal'

      else      puts  animal.name   end if  (some  object  whose  type  I  know)      I'll  supply  the  behavior   else      I'll  send  a  message   end
  166. Jan 2015 @sandimetz if  animal.is_a?(NilClass)      puts  'no  animal'

      else      puts  animal.name   end
  167. Jan 2015 @sandimetz if  animal.is_a?(NilClass)      puts  'no  animal'

      else      puts  animal.name   end
  168. Jan 2015 @sandimetz class  Animal      def  name  

         ...      end   end
  169. Jan 2015 @sandimetz class  Animal      def  name  

         ...      end   end   class  Nil      #  does  not  understand  name   end  
  170. Jan 2015 @sandimetz class  Animal      def  name  

         ...      end   end   class  ???      def  name          'no  animal'      end   end
  171. Jan 2015 @sandimetz class  Animal      def  name  

         ...      end   end   class  MissingAnimal      def  name          'no  animal'      end   end
  172. Jan 2015 @sandimetz Prefer knowing an object to duplicating behavior

  173. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)}   =>  [#<Animal:  @name="pig">,            nil,            #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   }
  174. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,            nil,            #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   }
  175. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,            nil,            #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   }
  176. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,            nil,            #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   }
  177. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   }
  178. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   } added dependency
  179. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   }
  180. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   } still have the condition
  181. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   } but no longer own the behavior
  182. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|      if  animal.is_a?(NilClass)          puts  'no  animal'      else          puts  animal.name      end   }
  183. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|          puts  animal.name   }
  184. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|        puts  animal.name   }
  185. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|  puts  animal.name}
  186. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|  puts  animal.name}   =>  'pig'          'no  animal'        'sheep'
  187. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|  puts  animal.name}   =>  'pig'          'no  animal'        'sheep'
  188. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|  puts  animal.name}   =>  'pig'          'no  animal'        'sheep'
  189. Jan 2015 @sandimetz class  Animal      def  name  

         ...      end   end   class  MissingAnimal      def  name          'no  animal'      end   end
  190. Jan 2015 @sandimetz

  191. Jan 2015 @sandimetz Null Object Pattern

  192. Jan 2015 @sandimetz Null Object Pattern 'Active Nothing'

  193. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   animals.each  {|animal|  puts  animal.name}   =>  'pig'          'no  animal'        'sheep'
  194. Jan 2015 @sandimetz ids  =  ['pig',  '',  'sheep']   animals

     =  ids.map  {|id|  Animal.find(id)  ||  MissingAnimal.new}   animals.each  {|animal|  puts  animal.name}   =>  'pig'          'no  animal'        'sheep' dependency
  195. Jan 2015 @sandimetz Prefer knowing an object to duplicating behavior

  196. Jan 2015 @sandimetz Prefer knowing few objects

  197. Jan 2015 @sandimetz class  Animal   def  self.find animal  =

     Animal.find(id)  ||  MissingAnimal.new   animal.name
  198. Jan 2015 @sandimetz class  Animal   def  self.find animal  =

     Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name
  199. Jan 2015 @sandimetz class  Animal   def  self.find  ||  MissingAnimal.new

      animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name al.find(id)  ||  MissingAnimal.new  
  200. Jan 2015 @sandimetz class  Animal   def  self.find  ||  MissingAnimal.new

      animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name al.find(id)  ||  MissingAnimal.new   )  ||  MissingAnimal.new   issingAnimal.new  
  201. Jan 2015 @sandimetz class  Animal   def  self.find  ||  MissingAnimal.new

      animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name al.find(id)  ||  MissingAnimal.new   )  ||  MissingAnimal.new   issingAnimal.new   MissingAnimal
  202. Jan 2015 @sandimetz class  Animal   def  self.find  ||  MissingAnimal.new

      animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name al.find(id)  ||  MissingAnimal.new   )  ||  MissingAnimal.new   issingAnimal.new   MissingAnimal MissingAnimal
  203. Jan 2015 @sandimetz class  Animal   def  self.find  ||  MissingAnimal.new

      animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name al.find(id)  ||  MissingAnimal.new   )  ||  MissingAnimal.new   issingAnimal.new   MissingAnimal MissingAnimal MissingAnimal
  204. Jan 2015 @sandimetz class  Animal   def  self.find  ||  MissingAnimal.new

      animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name al.find(id)  ||  MissingAnimal.new   )  ||  MissingAnimal.new   issingAnimal.new   MissingAnimal MissingAnimal MissingAnimal MissingAnimal
  205. Jan 2015 @sandimetz class  Animal   def  self.find  ||  MissingAnimal.new

      animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name animal  =  Animal.find(id)  ||  MissingAnimal.new   animal.name al.find(id)  ||  MissingAnimal.new   )  ||  MissingAnimal.new   issingAnimal.new   MissingAnimal MissingAnimal MissingAnimal MissingAnimal MissingAnimal   ???
  206. Jan 2015 @sandimetz class  Animal      def  self.find(id)  

           #  nil  or  an  Animal      end          #  …   end
  207. Jan 2015 @sandimetz class  Animal   def  self.find

  208. Jan 2015 @sandimetz class  GuaranteedAnimal   def  self.find class  Animal

      def  self.find
  209. Jan 2015 @sandimetz class  GuaranteedAnimal   def  self.find class  Animal

      def  self.find class  GuaranteedAnimal      def  self.find(id)          Animal.find(id)  ||  MissingAnimal.new      end   end
  210. Jan 2015 @sandimetz animals  =  ids.map  {|id|Animal.find(id)||MissingAnimal.new}

  211. Jan 2015 @sandimetz animals  =  ids.map  {|id|Animal.find(id)||MissingAnimal.new}

  212. Jan 2015 @sandimetz animals  =  ids.map  {|id|   GuaranteedAnimal.find(id)}  

    =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]
  213. Jan 2015 @sandimetz animals  =  ids.map  {|id|   GuaranteedAnimal.find(id)}  

    =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]
  214. Jan 2015 @sandimetz animals  =  ids.map  {|id|   GuaranteedAnimal.find(id)}  

    =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|  puts  animal.name  }   =>  'pig'        'no  animal'        'sheep'  
  215. Jan 2015 @sandimetz animals  =  ids.map  {|id|   GuaranteedAnimal.find(id)}  

    =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|  puts  animal.name  }   =>  'pig'        'no  animal'        'sheep'  
  216. Jan 2015 @sandimetz animals  =  ids.map  {|id|   GuaranteedAnimal.find(id)}  

    =>  [#<Animal:  @name="pig">,          #<MissingAnimal:>,          #<Animal:  @name="sheep">]   animals.each  {|animal|  puts  animal.name  }   =>  'pig'        'no  animal'        'sheep'  
  217. Jan 2015 @sandimetz Smalltalk Infected Condition Averse Message Centric

  218. Jan 2015 @sandimetz Smalltalk Infected Condition Averse Message Centric Abstraction

    Seeking
  219. Jan 2015 @sandimetz    'This  is  the  house  that  Jack

     built.' 1
  220. Jan 2015 @sandimetz    'This  is  the  house  that  Jack

     built.'      'This  is  the  malt  that  lay  in                          the  house  that  Jack  built.' 1 2
  221. Jan 2015 @sandimetz    'This  is  the  house  that  Jack

     built.'      'This  is  the  malt  that  lay  in                          the  house  that  Jack  built.'      'This  is  the  rat  that  ate                          the  malt  that  lay  in                          the  house  that  Jack  built.' 1 2 3
  222. Jan 2015 @sandimetz    'This  is  the  house  that  Jack

     built.'      'This  is  the  malt  that  lay  in                          the  house  that  Jack  built.'      'This  is  the  rat  that  ate                          the  malt  that  lay  in                          the  house  that  Jack  built.'    'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to                        the  farmer  sowing  his  corn  that  kept                        the  rooster  that  crowed  in  the  morn  that  woke                        the  priest  all  shaven  and  shorn  that  married                        the  man  all  tattered  and  torn  that  kissed                        the  maiden  all  forlorn  that  milked                        the  cow  with  the  crumpled  horn  that  tossed                        the  dog  that  worried                        the  cat  that  killed                          the  rat  that  ate                          the  malt  that  lay  in                          the  house  that  Jack  built.'   12
  223. Jan 2015 @sandimetz        [  'the  horse  and

     the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built'  ]  
  224. Jan 2015 @sandimetz    def  data        

     [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end  
  225. Jan 2015 @sandimetz    def  data        

     [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end  
  226. Jan 2015 @sandimetz    def  phrase(number)        

     data.last(number).join("  ")      end      def  data          [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end  
  227. Jan 2015 @sandimetz    def  phrase(number)        

     data.last(number).join("  ")      end      def  data          [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end   data.last(3)   =>  ['the  rat  that  ate',          'the  malt  that  lay  in',          'the  house  that  Jack  built']  
  228. Jan 2015 @sandimetz    def  phrase(number)        

     data.last(number).join("  ")      end      def  data          [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end  
  229. Jan 2015 @sandimetz    def  phrase(number)        

     data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end  
  230. Jan 2015 @sandimetz    def  phrase(number)        

     data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end  
  231. Jan 2015 @sandimetz    def  line(number)        

     "This  is  #{phrase(number)}.\n"      end      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end  
  232. Jan 2015 @sandimetz    def  line(number)        

     "This  is  #{phrase(number)}.\n"      end      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end  
  233. Jan 2015 @sandimetz    def  recite        

     (1..data.length).map  {|i|  line(i)}.join("\n")      end      def  line(number)          "This  is  #{phrase(number)}.\n"      end      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end  
  234. Jan 2015 @sandimetz    def  recite        

     (1..data.length).map  {|i|  line(i)}.join("\n")      end      def  line(number)          "This  is  #{phrase(number)}.\n"      end      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end  
  235. Jan 2015 @sandimetz class  House      def  recite  

           (1..data.length).map  {|i|  line(i)}.join("\n")      end      def  line(number)          "This  is  #{phrase(number)}.\n"      end      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  236. Jan 2015 @sandimetz

  237. Jan 2015 @sandimetz puts  House.new.line(1) =>  'This  is  the  house

     that  Jack  built.'
  238. Jan 2015 @sandimetz puts  House.new.line(1) =>  'This  is  the  house

     that  Jack  built.' puts  House.new.line(2) =>  'This  is  the  malt  that  lay  in  the  house  that  Jack  built.'
  239. Jan 2015 @sandimetz puts  House.new.line(1) =>  'This  is  the  house

     that  Jack  built.' puts  House.new.line(2) =>  'This  is  the  malt  that  lay  in  the  house  that  Jack  built.' puts  House.new.line(3) =>  'This  is  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.'
  240. Jan 2015 @sandimetz puts  House.new.line(1) =>  'This  is  the  house

     that  Jack  built.' puts  House.new.line(2) =>  'This  is  the  malt  that  lay  in  the  house  that  Jack  built.' puts  House.new.line(3) =>  'This  is  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.' puts  House.new.line(12) =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing   his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all   shaven  and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  maiden   all  forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog  that   worried  the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack   built.'
  241. Jan 2015 @sandimetz puts  House.new.line(1) =>  'This  is  the  house

     that  Jack  built.' puts  House.new.line(2) =>  'This  is  the  malt  that  lay  in  the  house  that  Jack  built.' puts  House.new.line(3) =>  'This  is  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.' puts  House.new.line(12) =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing   his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all   shaven  and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  maiden   all  forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog  that   worried  the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack   built.' puts  House.new.recite =>   'This  is  the  house  that  Jack  built.' 'This  is  the  malt  that  lay  in  the  house  that  Jack  built.' 'This  is  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.' etc
  242. Jan 2015 @sandimetz

  243. Jan 2015 @sandimetz New Feature Request:

  244. Jan 2015 @sandimetz New Feature Request: RandomHouse

  245. Jan 2015 @sandimetz        [  'the  horse  and

     the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built'  ]  
  246. Jan 2015 @sandimetz        [  'the  rooster  that

     crowed  in  the  morn  that  woke',              'the  farmer  sowing  his  corn  that  kept',              'the  dog  that  worried',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  malt  that  lay  in',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  house  that  Jack  built',              'the  cat  that  killed',              'the  maiden  all  forlorn  that  milked',              'the  rat  that  ate']
  247. Jan 2015 @sandimetz        [  'the  rooster  that

     crowed  in  the  morn  that  woke',              'the  farmer  sowing  his  corn  that  kept',              'the  dog  that  worried',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  malt  that  lay  in',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  house  that  Jack  built',              'the  cat  that  killed',              'the  maiden  all  forlorn  that  milked',              'the  rat  that  ate']
  248. Jan 2015 @sandimetz        [  'the  rooster  that

     crowed  in  the  morn  that  woke',              'the  farmer  sowing  his  corn  that  kept',              'the  dog  that  worried',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  malt  that  lay  in',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  house  that  Jack  built',              'the  cat  that  killed',              'the  maiden  all  forlorn  that  milked',              'the  rat  that  ate']
  249. Jan 2015 @sandimetz        [  'the  rooster  that

     crowed  in  the  morn  that  woke',              'the  farmer  sowing  his  corn  that  kept',              'the  dog  that  worried',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  malt  that  lay  in',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  house  that  Jack  built',              'the  cat  that  killed',              'the  maiden  all  forlorn  that  milked',              'the  rat  that  ate']
  250. Jan 2015 @sandimetz    'This  is  the  rat  that  ate.'

    1
  251. Jan 2015 @sandimetz    'This  is  the  rat  that  ate.'

         'This  is  the  maiden  all  forlorn  that  milked                          the  rat  that  ate.' 1 2
  252. Jan 2015 @sandimetz    'This  is  the  rat  that  ate.'

         'This  is  the  maiden  all  forlorn  that  milked                          the  rat  that  ate.'      'This  is  the  cat  that  killed                        the  maiden  all  forlorn  that  milked                          the  rat  that  ate.'   1 2 3
  253. Jan 2015 @sandimetz    'This  is  the  rat  that  ate.'

         'This  is  the  maiden  all  forlorn  that  milked                          the  rat  that  ate.'      'This  is  the  cat  that  killed                        the  maiden  all  forlorn  that  milked                          the  rat  that  ate.'      'This  is  the  rooster  that  crowed  in  the  morn  that  woke                          the  farmer  sowing  his  corn  that  kept                          the  dog  that  worried                          the  priest  all  shaven  and  shorn  that  married                          the  man  all  tattered  and  torn  that  kissed                          the  horse  and  the  hound  and  the  horn  that  belonged  to                          the  malt  that  lay  in                          the  cow  with  the  crumpled  horn  that  tossed                          the  house  that  Jack  built                          the  cat  that  killed                          the  maiden  all  forlorn  that  milked                          the  rat  that  ate.' 12
  254. Jan 2015 @sandimetz    'This  is  the  rat  that  ate.'

         'This  is  the  maiden  all  forlorn  that  milked                          the  rat  that  ate.'      'This  is  the  cat  that  killed                        the  maiden  all  forlorn  that  milked                          the  rat  that  ate.'      'This  is  the  rooster  that  crowed  in  the  morn  that  woke                          the  farmer  sowing  his  corn  that  kept                          the  dog  that  worried                          the  priest  all  shaven  and  shorn  that  married                          the  man  all  tattered  and  torn  that  kissed                          the  horse  and  the  hound  and  the  horn  that  belonged  to                          the  malt  that  lay  in                          the  cow  with  the  crumpled  horn  that  tossed                          the  house  that  Jack  built                          the  cat  that  killed                          the  maiden  all  forlorn  that  milked                          the  rat  that  ate.' 12
  255. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  256. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end Task: Implement RandomHouse without 'if' statements
  257. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end Inheritance?
  258. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  259. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  260. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  261. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  262. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  263. Jan 2015 @sandimetz

  264. Jan 2015 @sandimetz randomhouse  =  RandomHouse.new

  265. Jan 2015 @sandimetz randomhouse  =  RandomHouse.new puts  randomhouse.line(1) =>  'This

     is  the  rat  that  ate.'
  266. Jan 2015 @sandimetz randomhouse  =  RandomHouse.new puts  randomhouse.line(1) =>  'This

     is  the  rat  that  ate.' puts  randomhouse.line(2) =>  'This  is  the  maiden  all  forlorn  that  milked  the  rat  that  ate.'
  267. Jan 2015 @sandimetz randomhouse  =  RandomHouse.new puts  randomhouse.line(1) =>  'This

     is  the  rat  that  ate.' puts  randomhouse.line(2) =>  'This  is  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' puts  randomhouse.line(3) =>  'This  is  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat   that  ate.'
  268. Jan 2015 @sandimetz randomhouse  =  RandomHouse.new puts  randomhouse.line(1) =>  'This

     is  the  rat  that  ate.' puts  randomhouse.line(2) =>  'This  is  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' puts  randomhouse.line(3) =>  'This  is  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat   that  ate.' puts  randomhouse.line(12) =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  farmer   sowing  his  corn  that  kept  the  dog  that  worried  the  priest  all  shaven  and   shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  horse  and   the  hound  and  the  horn  that  belonged  to  the  malt  that  lay  in  the  cow  with   the  crumpled  horn  that  tossed  the  house  that  Jack  built  the  cat  that   killed  the  maiden  all  forlorn  that  milked  the  rat  that  ate.'
  269. Jan 2015 @sandimetz randomhouse  =  RandomHouse.new puts  randomhouse.line(1) =>  'This

     is  the  rat  that  ate.' puts  randomhouse.line(2) =>  'This  is  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' puts  randomhouse.line(3) =>  'This  is  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat   that  ate.' puts  randomhouse.line(12) =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  farmer   sowing  his  corn  that  kept  the  dog  that  worried  the  priest  all  shaven  and   shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  horse  and   the  hound  and  the  horn  that  belonged  to  the  malt  that  lay  in  the  cow  with   the  crumpled  horn  that  tossed  the  house  that  Jack  built  the  cat  that   killed  the  maiden  all  forlorn  that  milked  the  rat  that  ate.'
  270. Jan 2015 @sandimetz randomhouse  =  RandomHouse.new puts  randomhouse.line(1) =>  'This

     is  the  rat  that  ate.' puts  randomhouse.line(2) =>  'This  is  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' puts  randomhouse.line(3) =>  'This  is  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat   that  ate.' puts  randomhouse.line(12) =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  farmer   sowing  his  corn  that  kept  the  dog  that  worried  the  priest  all  shaven  and   shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  horse  and   the  hound  and  the  horn  that  belonged  to  the  malt  that  lay  in  the  cow  with   the  crumpled  horn  that  tossed  the  house  that  Jack  built  the  cat  that   killed  the  maiden  all  forlorn  that  milked  the  rat  that  ate.'
  271. Jan 2015 @sandimetz randomhouse  =  RandomHouse.new puts  randomhouse.line(1) =>  'This

     is  the  rat  that  ate.' puts  randomhouse.line(2) =>  'This  is  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' puts  randomhouse.line(3) =>  'This  is  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat   that  ate.' puts  randomhouse.line(12) =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  farmer   sowing  his  corn  that  kept  the  dog  that  worried  the  priest  all  shaven  and   shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  horse  and   the  hound  and  the  horn  that  belonged  to  the  malt  that  lay  in  the  cow  with   the  crumpled  horn  that  tossed  the  house  that  Jack  built  the  cat  that   killed  the  maiden  all  forlorn  that  milked  the  rat  that  ate.'
  272. Jan 2015 @sandimetz

  273. Jan 2015 @sandimetz New Feature Request:

  274. Jan 2015 @sandimetz New Feature Request: EchoHouse

  275. Jan 2015 @sandimetz

  276. Jan 2015 @sandimetz This  is  the  house  that  Jack  built

     the  house  that  Jack  built.
  277. Jan 2015 @sandimetz This  is  the  house  that  Jack  built

     the  house  that  Jack  built.
  278. Jan 2015 @sandimetz This  is  the  house  that  Jack  built

     the  house  that  Jack  built. This  is  the  malt  that  lay  in  the  malt  that  lay  in                  the  house  that  Jack  built  the  house  that  Jack  built.
  279. Jan 2015 @sandimetz This  is  the  house  that  Jack  built

     the  house  that  Jack  built. This  is  the  malt  that  lay  in  the  malt  that  lay  in                  the  house  that  Jack  built  the  house  that  Jack  built.
  280. Jan 2015 @sandimetz This  is  the  house  that  Jack  built

     the  house  that  Jack  built. This  is  the  malt  that  lay  in  the  malt  that  lay  in                  the  house  that  Jack  built  the  house  that  Jack  built. This  is  the  rat  that  ate  the  rat  that  ate                  the  malt  that  lay  in  the  malt  that  lay  in                  the  house  that  Jack  built  the  house  that  Jack  built.
  281. Jan 2015 @sandimetz class  House      def  recite  

           (1..data.length).map  {|i|  line(i)}.join("\n")      end      def  line(number)          "This  is  #{phrase(number)}.\n"      end      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  282. Jan 2015 @sandimetz class  House      def  recite  

           (1..data.length).map  {|i|  line(i)}.join("\n")      end      def  line(number)          "This  is  #{phrase(number)}.\n"      end      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  283. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  284. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  285. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)          data.last(number).join("  ")      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  286. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)          data.last(number).join("  ")      end      def  parts(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  287. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)          data.last(number).join("  ")      end      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  288. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)          parts(number).join("  ")      end      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  289. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)          parts(number).join("  ")      end      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  290. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  291. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end ['the  rat  that  ate',    'the  malt  that  lay  in',    'the  house  that  Jack  built'] have
  292. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end ['the  rat  that  ate',    'the  malt  that  lay  in',    'the  house  that  Jack  built'] ['the  rat  that  ate',    'the  rat  that  ate',    'the  malt  that  lay  in',    'the  malt  that  lay  in',    'the  house  that  Jack  built',    'the  house  that  Jack  built'] want
  293. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end
  294. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end Task: Implement EchoHouse without 'if' statements
  295. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end Inheritance?
  296. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end
  297. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end
  298. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end
  299. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end
  300. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end
  301. Jan 2015 @sandimetz ['the  rat  that  ate',    'the  malt

     that  lay  in',    'the  house  that  Jack  built']
  302. Jan 2015 @sandimetz ['the  rat  that  ate',    'the  malt

     that  lay  in',    'the  house  that  Jack  built'] ['the  rat  that  ate',    'the  malt  that  lay  in',    'the  house  that  Jack  built']
  303. Jan 2015 @sandimetz ['the  rat  that  ate',    'the  malt

     that  lay  in',    'the  house  that  Jack  built'] ['the  rat  that  ate',    'the  malt  that  lay  in',    'the  house  that  Jack  built'] super.zip(super)
  304. Jan 2015 @sandimetz ['the  rat  that  ate',    'the  malt

     that  lay  in',    'the  house  that  Jack  built'] ['the  rat  that  ate',    'the  malt  that  lay  in',    'the  house  that  Jack  built'] [['the  rat  that  ate','the  rat  that  ate'],    ['the  malt  that  lay  in','the  malt  that  lay  in'],    ['the  house  that  Jack  built','the  house  that  Jack  built']] super.zip(super)
  305. Jan 2015 @sandimetz ['the  rat  that  ate',    'the  malt

     that  lay  in',    'the  house  that  Jack  built'] super.zip(super).flatten ['the  rat  that  ate',    'the  malt  that  lay  in',    'the  house  that  Jack  built'] [['the  rat  that  ate','the  rat  that  ate'],    ['the  malt  that  lay  in','the  malt  that  lay  in'],    ['the  house  that  Jack  built','the  house  that  Jack  built']] super.zip(super)
  306. Jan 2015 @sandimetz ['the  rat  that  ate',    'the  malt

     that  lay  in',    'the  house  that  Jack  built'] super.zip(super).flatten ['the  rat  that  ate',    'the  malt  that  lay  in',    'the  house  that  Jack  built'] [['the  rat  that  ate','the  rat  that  ate'],    ['the  malt  that  lay  in','the  malt  that  lay  in'],    ['the  house  that  Jack  built','the  house  that  Jack  built']] super.zip(super) ['the  rat  that  ate','the  rat  that  ate',    'the  malt  that  lay  in','the  malt  that  lay  in',    'the  house  that  Jack  built','the  house  that  Jack  built']
  307. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)          data.last(number)      end      def  data              [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',                  #  ...                  'the  malt  that  lay  in',                  'the  house  that  Jack  built']      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end
  308. Jan 2015 @sandimetz

  309. Jan 2015 @sandimetz puts  EchoHouse.new.line(1) 'This  is  the  house  that

     Jack  built  the  house  that  Jack  built.'
  310. Jan 2015 @sandimetz puts  EchoHouse.new.line(1) 'This  is  the  house  that

     Jack  built  the  house  that  Jack  built.' puts  EchoHouse.new.line(2) 'This  is  the  malt  that  lay  in  the  malt  that  lay  in  the  house  that  Jack  built  the   house  that  Jack  built.'
  311. Jan 2015 @sandimetz puts  EchoHouse.new.line(1) 'This  is  the  house  that

     Jack  built  the  house  that  Jack  built.' puts  EchoHouse.new.line(2) 'This  is  the  malt  that  lay  in  the  malt  that  lay  in  the  house  that  Jack  built  the   house  that  Jack  built.' puts  EchoHouse.new.line(3) 'This  is  the  rat  that  ate  the  rat  that  ate  the  malt  that  lay  in  the  malt  that  lay  in   the  house  that  Jack  built  the  house  that  Jack  built.'
  312. Jan 2015 @sandimetz puts  EchoHouse.new.line(1) 'This  is  the  house  that

     Jack  built  the  house  that  Jack  built.' puts  EchoHouse.new.line(2) 'This  is  the  malt  that  lay  in  the  malt  that  lay  in  the  house  that  Jack  built  the   house  that  Jack  built.' puts  EchoHouse.new.line(3) 'This  is  the  rat  that  ate  the  rat  that  ate  the  malt  that  lay  in  the  malt  that  lay  in   the  house  that  Jack  built  the  house  that  Jack  built.' puts  EchoHouse.new.line(12) 'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  horse  and  the   hound  and  the  horn  that  belonged  to  the  farmer  sowing  his  corn  that  kept  the  farmer   sowing  his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  rooster   that  crowed  in  the  morn  that  woke  the  priest  all  shaven  and  shorn  that  married  the   priest  all  shaven  and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed   the  man  all  tattered  and  torn  that  kissed  the  maiden  all  forlorn  that  milked  the   maiden  all  forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  cow   with  the  crumpled  horn  that  tossed  the  dog  that  worried  the  dog  that  worried  the  cat   that  killed  the  cat  that  killed  the  rat  that  ate  the  rat  that  ate  the  malt  that  lay   in  the  malt  that  lay  in  the  house  that  Jack  built  the  house  that  Jack  built.'
  313. Jan 2015 @sandimetz class  House      def  recite  

       def  line(number)      def  phrase(number)      def  parts(number)      def  data   end
  314. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  House      def  recite      def  line(number)      def  phrase(number)      def  parts(number)      def  data   end
  315. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  House      def  recite      def  line(number)      def  phrase(number)      def  parts(number)      def  data   end
  316. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  House      def  recite      def  line(number)      def  phrase(number)      def  parts(number)      def  data   end
  317. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  House      def  recite      def  line(number)      def  phrase(number)      def  parts(number)      def  data   end
  318. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  House      def  recite      def  line(number)      def  phrase(number)      def  parts(number)      def  data   end What could possibly go wrong?
  319. Jan 2015 @sandimetz

  320. Jan 2015 @sandimetz New Feature Request:

  321. Jan 2015 @sandimetz New Feature Request: RandomEchoHouse

  322. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  House      def  recite      def  line(number)      def  phrase(number)      def  parts(number)      def  data   end
  323. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end
  324. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end
  325. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end Duplicate some of the code?
  326. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end RandomEchoHouse <  RandomHouse <  EchoHouse data parts
  327. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end   class  RandomEchoHouse  <  RandomHouse      def  parts(number)          super.zip(super).flatten      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end RandomEchoHouse <  RandomHouse <  EchoHouse data parts
  328. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end   class  RandomEchoHouse  <  RandomHouse      def  parts(number)          super.zip(super).flatten      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end RandomEchoHouse <  RandomHouse <  EchoHouse data parts
  329. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end   class  RandomEchoHouse  <  RandomHouse      def  parts(number)          super.zip(super).flatten      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end RandomEchoHouse <  RandomHouse <  EchoHouse Inherit data parts
  330. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end   class  RandomEchoHouse  <  RandomHouse      def  parts(number)          super.zip(super).flatten      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end RandomEchoHouse <  RandomHouse <  EchoHouse Inherit data Duplicate parts
  331. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end RandomEchoHouse <  RandomHouse <  EchoHouse Inherit data Duplicate parts
  332. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end   class   RandomEchoHouse   <   EchoHouse      def  data          @data  ||=  super.shuffle      end   end RandomEchoHouse <  RandomHouse <  EchoHouse Inherit data Duplicate parts
  333. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end   class   RandomEchoHouse   <   EchoHouse      def  data          @data  ||=  super.shuffle      end   end RandomEchoHouse <  RandomHouse <  EchoHouse Inherit data Duplicate parts
  334. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end   class   RandomEchoHouse   <   EchoHouse      def  data          @data  ||=  super.shuffle      end   end RandomEchoHouse <  RandomHouse <  EchoHouse Inherit data Duplicate parts Inherit
  335. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end   class   RandomEchoHouse   <   EchoHouse      def  data          @data  ||=  super.shuffle      end   end RandomEchoHouse <  RandomHouse <  EchoHouse Inherit data Duplicate Duplicate parts Inherit
  336. Jan 2015 @sandimetz class  RandomHouse  <  House   class  EchoHouse

     <  House  
  337. Jan 2015 @sandimetz class  RandomHouse  <  House   class  EchoHouse

     <  House   Duplicate all of the code!
  338. Jan 2015 @sandimetz class  RandomHouse  <  House   class  EchoHouse

     <  House   class  RandomEchoHouse  <  House  
  339. Jan 2015 @sandimetz class  RandomHouse  <  House   class  EchoHouse

     <  House   class  RandomEchoHouse  <  House  
  340. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  RandomEchoHouse  <  House      def  data          @data  ||=  super.shuffle      end      def  parts(number)          super.zip(super).flatten      end   end
  341. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  RandomEchoHouse  <  House      def  data          @data  ||=  super.shuffle      end      def  parts(number)          super.zip(super).flatten      end   end
  342. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  RandomEchoHouse  <  House      def  data          @data  ||=  super.shuffle      end      def  parts(number)          super.zip(super).flatten      end   end
  343. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  RandomEchoHouse  <  House      def  data          @data  ||=  super.shuffle      end      def  parts(number)          super.zip(super).flatten      end   end
  344. Jan 2015 @sandimetz class  RandomHouse  <  House      def

     data          @data  ||=  super.shuffle      end   end class  EchoHouse  <  House      def  parts(number)          super.zip(super).flatten      end   end class  RandomEchoHouse  <  House      def  data          @data  ||=  super.shuffle      end      def  parts(number)          super.zip(super).flatten      end   end
  345. Jan 2015 @sandimetz House

  346. Jan 2015 @sandimetz House Random House Echo House

  347. Jan 2015 @sandimetz House Echo House Random House

  348. Jan 2015 @sandimetz House Echo House Random House

  349. Jan 2015 @sandimetz House Echo House Random House Random House

  350. Jan 2015 @sandimetz House Echo House Random House Random House

  351. Jan 2015 @sandimetz House Echo House Random House Random House

  352. Jan 2015 @sandimetz House Echo House Random House Random House

    Echo House
  353. Jan 2015 @sandimetz House Echo House Random House Random House

    Echo House
  354. Jan 2015 @sandimetz Echo House Random House Random House Echo

    House
  355. Jan 2015 @sandimetz Random House Echo House

  356. Jan 2015 @sandimetz Random House Echo House

  357. Jan 2015 @sandimetz Random House Echo House RandomEcho House

  358. Jan 2015 @sandimetz Random House Echo House RandomEcho House

  359. Jan 2015 @sandimetz Random House Echo House RandomEcho House

  360. Jan 2015 @sandimetz Random House Echo House RandomEcho House

  361. Jan 2015 @sandimetz Random House Echo House RandomEcho House

  362. Jan 2015 @sandimetz Random House Echo House RandomEcho House

  363. Jan 2015 @sandimetz Random House Echo House RandomEcho House

  364. Jan 2015 @sandimetz Random House Echo House RandomEcho House

  365. Jan 2015 @sandimetz Random House Echo House

  366. Jan 2015 @sandimetz Random House Echo House

  367. Jan 2015 @sandimetz Random House Echo House

  368. Jan 2015 @sandimetz

  369. Jan 2015 @sandimetz Inheritance

  370. Jan 2015 @sandimetz Inheritance is for specialization

  371. Jan 2015 @sandimetz Inheritance is for specialization is not for

    sharing code
  372. Jan 2015 @sandimetz RandomHouse is-a House?

  373. Jan 2015 @sandimetz class  House      def  data  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end   end   class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  374. Jan 2015 @sandimetz class  House      def  data  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end   end   class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end What does RandomHouse change?
  375. Jan 2015 @sandimetz Reveal how things differ by making them

    more alike
  376. Jan 2015 @sandimetz class  House      def  data  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end   end   class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  377. Jan 2015 @sandimetz class  House      def  data  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end   end   class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end Make this
  378. Jan 2015 @sandimetz class  House      def  data  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end   end   class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end Make this More like this
  379. Jan 2015 @sandimetz class  House      def  data  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']      end   end
  380. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              'the  farmer  sowing  his  corn  that  kept',              'the  rooster  that  crowed  in  the  morn  that  woke',              'the  priest  all  shaven  and  shorn  that  married',              'the  man  all  tattered  and  torn  that  kissed',              'the  maiden  all  forlorn  that  milked',              'the  cow  with  the  crumpled  horn  that  tossed',              'the  dog  that  worried',              'the  cat  that  killed',              'the  rat  that  ate',              'the  malt  that  lay  in',              'the  house  that  Jack  built']   end
  381. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']   end
  382. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      def  data          DATA      end   end
  383. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      def  data          DATA      end   end   class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  384. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      def  data          @data  ||=  DATA      end   end   class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  385. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      def  data          @data  ||=  DATA      end   end   class  RandomHouse  <  House      def  data          @data  ||=  DATA.shuffle      end   end
  386. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      def  data          @data  ||=  DATA      end   end   class  RandomHouse  <  House      def  data          @data  ||=  DATA.shuffle      end   end What changed?
  387. Jan 2015 @sandimetz Name the concept

  388. Jan 2015 @sandimetz House RandomHouse

  389. Jan 2015 @sandimetz House DATA RandomHouse DATA

  390. Jan 2015 @sandimetz House DATA RandomHouse DATA shuffle

  391. Jan 2015 @sandimetz class House DATA RandomHouse DATA shuffle

  392. Jan 2015 @sandimetz class data House DATA RandomHouse DATA shuffle

  393. Jan 2015 @sandimetz class data ????? House DATA RandomHouse DATA

    shuffle
  394. Jan 2015 @sandimetz class data random?? House DATA RandomHouse DATA

    shuffle
  395. Jan 2015 @sandimetz class data order! House DATA RandomHouse DATA

    shuffle
  396. Jan 2015 @sandimetz class data order House DATA RandomHouse DATA

    shuffle
  397. Jan 2015 @sandimetz class data order House DATA RandomHouse DATA

    shuffle This is not nothing
  398. Jan 2015 @sandimetz class data order House DATA RandomHouse DATA

    shuffle It's an order algorithm
  399. Jan 2015 @sandimetz class data order House DATA RandomHouse DATA

    shuffle It's an order algorithm just as valid as this one
  400. Jan 2015 @sandimetz Order is-a House?

  401. Jan 2015 @sandimetz Orderer is a role

  402. Jan 2015 @sandimetz class  RandomOrder      def  order(data)  

           data.shuffle      end   end
  403. Jan 2015 @sandimetz class  DefaultOrder   end   class  RandomOrder

         def  order(data)          data.shuffle      end   end
  404. Jan 2015 @sandimetz class  DefaultOrder      def  order(data)  

       end   end   class  RandomOrder      def  order(data)          data.shuffle      end   end
  405. Jan 2015 @sandimetz class  DefaultOrder      def  order(data)  

           data      end   end   class  RandomOrder      def  order(data)          data.shuffle      end   end
  406. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      def  data          DATA      end   end   class  RandomHouse  <  House      def  data          @data  ||=  super.shuffle      end   end
  407. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      def  data          DATA      end   end
  408. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      def  data          DATA      end        #  ...   end
  409. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      attr_reader  :data      def  data          DATA      end        #  ...   end
  410. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      attr_reader  :data      def  initialize          @data  =  DATA      end      def  data          DATA      end        #  ...   end
  411. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      attr_reader  :data      def  initialize          @data  =  DATA      end        #  ...   end
  412. Jan 2015 @sandimetz class  House      DATA  =  

           [  'the  horse  and  the  hound  and  the  horn  that  belonged  to',              #  ...            'the  house  that  Jack  built']      attr_reader  :data      def  initialize          @data  =  DATA      end        #  ...   end
  413. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize          @data  =  DATA      end        #  ...   end
  414. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize          @data  =  DATA      end        #  ...   end
  415. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize          @data  =  DATA      end        #  ...   end Remove 'ordering' responsibility from House
  416. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize          @data  =  DATA      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end
  417. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  DATA      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end
  418. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =                              DATA      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end
  419. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end
  420. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new.line(12)
  421. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new.line(12) =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing   his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all  shaven   and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  maiden  all   forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog  that  worried   the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.'
  422. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new.line(12)   =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing   his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all  shaven   and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  maiden  all   forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog  that  worried   the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.'
  423. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new.line(12)   =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing   his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all  shaven   and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  maiden  all   forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog  that  worried   the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.' More code
  424. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new.line(12)   =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing   his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all  shaven   and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  maiden  all   forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog  that  worried   the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.' More code Same behavior
  425. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new.line(12)   =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing   his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all  shaven   and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  maiden  all   forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog  that  worried   the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.' More code Same behavior Awesome
  426. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new.line(12)   =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing   his  corn  that  kept  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all  shaven   and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  maiden  all   forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog  that  worried   the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.'
  427. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new.line(12) class  RandomOrder      def  order(data)          data.shuffle      end   end
  428. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new(                                                ).line(12) class  RandomOrder      def  order(data)          data.shuffle      end   end
  429. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new(orderer:  RandomOrder.new).line(12) class  RandomOrder      def  order(data)          data.shuffle      end   end
  430. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new(orderer:  RandomOrder.new).line(12)   =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  farmer  sowing  his  corn   that  kept  the  dog  that  worried  the  priest  all  shaven  and  shorn  that  married  the  man   all  tattered  and  torn  that  kissed  the  horse  and  the  hound  and  the  horn  that  belonged   to  the  malt  that  lay  in  the  cow  with  the  crumpled  horn  that  tossed  the  house  that  Jack   built  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' class  RandomOrder      def  order(data)          data.shuffle      end   end
  431. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new(orderer:  RandomOrder.new).line(12)   =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  farmer  sowing  his  corn   that  kept  the  dog  that  worried  the  priest  all  shaven  and  shorn  that  married  the  man   all  tattered  and  torn  that  kissed  the  horse  and  the  hound  and  the  horn  that  belonged   to  the  malt  that  lay  in  the  cow  with  the  crumpled  horn  that  tossed  the  house  that  Jack   built  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' class  RandomOrder      def  order(data)          data.shuffle      end   end
  432. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new(orderer:  RandomOrder.new).line(12)   =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  farmer  sowing  his  corn   that  kept  the  dog  that  worried  the  priest  all  shaven  and  shorn  that  married  the  man   all  tattered  and  torn  that  kissed  the  horse  and  the  hound  and  the  horn  that  belonged   to  the  malt  that  lay  in  the  cow  with  the  crumpled  horn  that  tossed  the  house  that  Jack   built  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' class  RandomOrder      def  order(data)          data.shuffle      end   end
  433. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new(orderer:  RandomOrder.new).line(12)   =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  farmer  sowing  his  corn   that  kept  the  dog  that  worried  the  priest  all  shaven  and  shorn  that  married  the  man   all  tattered  and  torn  that  kissed  the  horse  and  the  hound  and  the  horn  that  belonged   to  the  malt  that  lay  in  the  cow  with  the  crumpled  horn  that  tossed  the  house  that  Jack   built  the  cat  that  killed  the  maiden  all  forlorn  that  milked  the  rat  that  ate.' class  RandomOrder      def  order(data)          data.shuffle      end   end
  434. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new(orderer:  RandomOrder.new).line(12)   =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  cat  that  killed  the  cow   with  the  crumpled  horn  that  tossed  the  horse  and  the  hound  and  the  horn  that  belonged   to  the  farmer  sowing  his  corn  that  kept  the  priest  all  shaven  and  shorn  that  married   the  man  all  tattered  and  torn  that  kissed  the  house  that  Jack  built  the  malt  that  lay   in  the  rat  that  ate  the  maiden  all  forlorn  that  milked  the  dog  that  worried.' class  RandomOrder      def  order(data)          data.shuffle      end   end Composition
  435. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultOrder      def  order(data)          data      end   end puts  House.new(orderer:  RandomOrder.new).line(12)   =>  'This  is  the  rooster  that  crowed  in  the  morn  that  woke  the  cat  that  killed  the  cow   with  the  crumpled  horn  that  tossed  the  horse  and  the  hound  and  the  horn  that  belonged   to  the  farmer  sowing  his  corn  that  kept  the  priest  all  shaven  and  shorn  that  married   the  man  all  tattered  and  torn  that  kissed  the  house  that  Jack  built  the  malt  that  lay   in  the  rat  that  ate  the  maiden  all  forlorn  that  milked  the  dog  that  worried.' class  RandomOrder      def  order(data)          data.shuffle      end   end Inject an object to play the role of the thing that varies
  436. Jan 2015 @sandimetz Echo?

  437. Jan 2015 @sandimetz class  EchoFormatter      def  format(parts)  

           parts.zip(parts).flatten      end   end
  438. Jan 2015 @sandimetz class  DefaultFormatter      def  format(parts)  

           parts      end   end   class  EchoFormatter      def  format(parts)          parts.zip(parts).flatten      end   end
  439. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end
  440. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def  initialize(orderer:  DefaultOrder.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  441. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  442. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  443. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data  =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  444. Jan 2015 @sandimetz class  House      attr_reader  :data  

       def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  445. Jan 2015 @sandimetz class  House      attr_reader    

                         :data      def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  446. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  447. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  448. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end      def  parts(number)        data.last(number)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  449. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end      def  parts(number)                                            data.last(number)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  450. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end      def  parts(number)          formatter.format(data.last(number))      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  451. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  452. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end class  DefaultFormatter      def  format(parts)          parts      end   end
  453. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end puts  House.new.line(12) class  DefaultFormatter      def  format(parts)          parts      end   end
  454. Jan 2015 @sandimetz class  House      attr_reader  :formatter,  :data

         def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end puts  House.new.line(12) =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  farmer  sowing  his  corn  that  kept  the   rooster  that  crowed  in  the  morn  that  woke  the  priest  all  shaven  and  shorn  that  married  the  man  all  tattered   and  torn  that  kissed  the  maiden  all  forlorn  that  milked  the  cow  with  the  crumpled  horn  that  tossed  the  dog   that  worried  the  cat  that  killed  the  rat  that  ate  the  malt  that  lay  in  the  house  that  Jack  built.' class  DefaultFormatter      def  format(parts)          parts      end   end
  455. Jan 2015 @sandimetz class  DefaultFormatter      def  format(parts)  

           parts      end   end class  House      attr_reader  :formatter,  :data      def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end class  EchoFormatter      def  format(parts)          parts.zip(parts).flatten      end   end
  456. Jan 2015 @sandimetz class  DefaultFormatter      def  format(parts)  

           parts      end   end class  House      attr_reader  :formatter,  :data      def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end puts  House.new(formatter:  EchoFormatter.new).line(12) class  EchoFormatter      def  format(parts)          parts.zip(parts).flatten      end   end
  457. Jan 2015 @sandimetz class  DefaultFormatter      def  format(parts)  

           parts      end   end class  House      attr_reader  :formatter,  :data      def   initialize(orderer:   DefaultOrder.new,   formatter:   DefaultFormatter.new)          @formatter  =  formatter          @data            =  orderer.order(DATA)      end        #  ...   end puts  House.new(formatter:  EchoFormatter.new).line(12) =>  'This  is  the  horse  and  the  hound  and  the  horn  that  belonged  to  the  horse  and  the  hound  and  the  horn  that   belonged  to  the  farmer  sowing  his  corn  that  kept  the  farmer  sowing  his  corn  that  kept  the  rooster  that   crowed  in  the  morn  that  woke  the  rooster  that  crowed  in  the  morn  that  woke  the  priest  all  shaven  and  shorn   that  married  the  priest  all  shaven  and  shorn  that  married  the  man  all  tattered  and  torn  that  kissed  the  man class  EchoFormatter      def  format(parts)          parts.zip(parts).flatten      end   end
  458. Jan 2015 @sandimetz class  DefaultOrder      def  order(data)  

           data      end   end class  RandomOrder      def  order(data)          data.shuffle      end   end Orderer Role
  459. Jan 2015 @sandimetz class  DefaultFormatter      def  format(parts)  

           parts      end   end class  EchoFormatter      def  format(parts)          parts.zip(parts).flatten      end   end class  DefaultOrder      def  order(data)          data      end   end class  RandomOrder      def  order(data)          data.shuffle      end   end Orderer Role Formatter Role
  460. Jan 2015 @sandimetz puts  House.new.line(12)

  461. Jan 2015 @sandimetz

  462. Jan 2015 @sandimetz puts  House.new.recite

  463. Jan 2015 @sandimetz puts  House.new.recite puts  House.new(orderer:  RandomOrder.new).recite

  464. Jan 2015 @sandimetz puts  House.new.recite puts  House.new(orderer:  RandomOrder.new).recite puts  House.new(formatter:

     EchoFormatter.new).recite
  465. Jan 2015 @sandimetz puts  House.new.recite puts  House.new(orderer:  RandomOrder.new).recite puts  House.new(formatter:

     EchoFormatter.new).recite puts  House.new(orderer:      RandomOrder.new,                                formatter:  EchoFormatter.new).recite
  466. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite More code?
  467. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite
  468. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite Less code!
  469. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite Less code! No duplication
  470. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite Less code! Pluggable behavior
  471. Jan 2015 @sandimetz House Echo House Random House

  472. Jan 2015 @sandimetz House

  473. Jan 2015 @sandimetz House

  474. Jan 2015 @sandimetz House 1) Isolate the thing that varies

  475. Jan 2015 @sandimetz House 1) Isolate the thing that varies

  476. Jan 2015 @sandimetz House 1) Isolate the thing that varies

  477. Jan 2015 @sandimetz House

  478. Jan 2015 @sandimetz House

  479. Jan 2015 @sandimetz House 2) Name the Concept

  480. Jan 2015 @sandimetz House 2) Name the Concept

  481. Jan 2015 @sandimetz House Order Format

  482. Jan 2015 @sandimetz House Order Format 3) Define the Role

  483. Jan 2015 @sandimetz House Order Format 3) Define the Role

  484. Jan 2015 @sandimetz House Orderer Formatter

  485. Jan 2015 @sandimetz House Orderer Formatter 4) Inject the player

  486. Jan 2015 @sandimetz House Orderer Formatter

  487. Jan 2015 @sandimetz House Orderer Formatter

  488. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite
  489. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite Composition
  490. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite Composition + Dependency Injection
  491. Jan 2015 @sandimetz puts  House.new.recite   puts  House.new(orderer:  RandomOrder.new).recite  

    puts  House.new(formatter:  EchoFormatter.new).recite   puts  House.new(orderer:      RandomOrder.new,                                  formatter:  EchoFormatter.new).recite Object-Oriented Design
  492. Jan 2015 @sandimetz Smalltalk Infected Condition Averse Message Centric Abstraction

    Seeking
  493. Jan 2015 @sandimetz Smalltalk Infected Condition Averse Message Centric Abstraction

    Seeking
  494. Jan 2015 @sandimetz Summary

  495. Jan 2015 @sandimetz

  496. Jan 2015 @sandimetz If you're talking to nil

  497. Jan 2015 @sandimetz If you're talking to nil it's something

  498. Jan 2015 @sandimetz Null Object Pattern Active Nothing

  499. Jan 2015 @sandimetz

  500. Jan 2015 @sandimetz Ware Inheritance

  501. Jan 2015 @sandimetz Ware Inheritance It is not for sharing

    behavior
  502. Jan 2015 @sandimetz There's no such thing as one specialization

  503. Jan 2015 @sandimetz

  504. Jan 2015 @sandimetz Isolate the thing that varies

  505. Jan 2015 @sandimetz Isolate the thing that varies Name the

    concept
  506. Jan 2015 @sandimetz Isolate the thing that varies Name the

    concept Define the role
  507. Jan 2015 @sandimetz Isolate the thing that varies Name the

    concept Define the role Inject the players
  508. Jan 2015 @sandimetz Believe in nothing

  509. Jan 2015 @sandimetz Nothing is always Something

  510. Jan 2015 @sandimetz Sandi Metz @sandimetz http://sandimetz.com

  511. Jan 2015 @sandimetz http://poodr.com

  512. Jan 2015 @sandimetz http://99bottlesbook.com Practical Programming Book 99 Bottles of

    OOP
  513. Jan 2015 @sandimetz Next Public Course POODNYC Oct 19-21, 2015

    New York City
  514. Jan 2015 @sandimetz Stickers?

  515. Jan 2015 @sandimetz Stickers?

  516. Jan 2015 @sandimetz Temporary Tattoos!

  517. Jan 2015 @sandimetz Thanks

  518. Jan 2015 @sandimetz Sandi Metz @sandimetz http://sandimetz.com