# Awesome: duck typing!!! # Lame: code duplication!!! class Fixnum def double self+self end end class String def double self+self end end =begin # Better... Now we hit all subclasses of # Numeric including Fixnum and Float # but not String. There is still code # duplication if we want String to # have the double method. class Numeric def double self+self end end =end # Mixins: purely for code reuse!!! module Doublable def double self+self end end class Fixnum include Doublable end class String include Doublable end # The Comparable Mixin class Point # include Comparable attr_reader :x, :y def initialize(x=0,y=0) @x = x @y = y end def <=> other significant = x <=> other.x return significant if significant != 0 y <=> other.y end # More Java-like version of <=> (but # same behavior) def compareTo other if x != other.x (x-other.x).sign else (y-other.y).sign end end end class Numeric def sign self <=> 0 end end # Simple BinaryTree with insert and # lookup methods class BinaryTree class Node attr_accessor :left, :right attr_reader :data def initialize(data, left=nil, right=nil) @data = data @left = left @right = right end end def insert el @root = insert_(el, @root) end def lookup el lookup_(el, @root) end private def insert_ el, root return Node.new(el) unless root if el < root.data root.left = insert_(el, root.left) else root.right = insert_(el, root.right) end root end def lookup_ el, root return el if root.data == el if el < root.data lookup_(el, root.left) else lookup_(el, root.right) end end end # Let's add an iterator class BinaryTree def each each_(@root) { |x| yield x } end private def each_ root if root each_(root.left) { |x| yield x } yield root.data each_(root.right) { |x| yield x } end end end =begin # Let's add 47 other awesome methods class BinaryTree include Enumerable end =begin =end