completely useless ruby code

Posted by phillip Tue, 31 Jan 2006 22:25:00 GMT

this chunk of code is completely useless, apart from the fact that it let me practise how ruby does arrays, objects, constants, observers and singletons. and how to pass a variable number of arguments to a function method and set defaults for arguments that weren’t passed. plus it had me thinking about “what-goes-where” and coupling in object oriented programming.

maybe not so useless after all!

#
# for documentation see the UML diagram at the following url
# @url <a href="http://www.flickr.com/photos/calicojane/93113537">http://www.flickr.com/photos/calicojane/93113537</a>
#
require 'observer'
require 'singleton'

class StickFigure
   MALE = 0
   FEMALE = 1   
   attr_reader :name
   def initialize(attrs)
      @name     = attrs[:name] ||= 'Anonymous Coward'
      @sex      = attrs[:sex] ||= MALE
      @is_lazy  = attrs[:is_lazy] ||= false
      @in_peril = false
   end
   def in_peril!
      @in_peril = true
      puts @name + ' is in peril!'
   end
   def to_s
      puts "\nHi! I'm " + @name + ' and I am ' + (@is_lazy == true ? 'a little' : 'not') + ' lazy.'
   end   
   alias :introduce_self :to_s   
end

class CoffeeDrinkingStickFigure < StickFigure
   def have_coffee
      puts @name + ' has a cup of coffee.'
      pot = get_coffee_pot
      pot.pour_coffee
      if pot.needs_refill?
         make_more_coffee unless @is_lazy
      end
      return_to_desk
   end

   #
   # :TODO: the stickfigure should NOT be responsible for notifying it's observer ... better solution?
   # this part is not so pretty.
   # 
   def return_to_desk
      puts @name + ' returns to ' + (@sex == FEMALE ? 'her' : 'his') + ' desk.'
      get_coffee_pot.notify_observers(get_coffee_pot, self)
   end   
   def make_more_coffee
      puts @name + ' refills the coffee pot.'
      pot = get_coffee_pot
      pot.refill
   end   
   private
   def get_coffee_pot
      CoffeePot.instance
   end   
end

class CoffeePot
   include Singleton
   include Observable
   attr_reader :cups_left
   CUPS_WHEN_FULL = 2.5   
   def initialize
      @cups_left = 0
      self.refill
      self.add_observer(BigBrother.new)
   end   
   def pour_coffee
      @cups_left -= 1
      changed
   end   
   def refill
      @cups_left = CUPS_WHEN_FULL
      changed
   end
   def is_empty?
      @cups_left == 0
   end   
   def needs_refill?
      @cups_left < 1
   end   
end

class BigBrother
   def update(pot, who_got_coffee)
      if pot.needs_refill?
         puts 'The coffee pot needs a refill and ' + who_got_coffee.name + " didn't refill it!\n"
         who_got_coffee.in_peril!
      else 
         cup_string = pot.cups_left == 1 ? 'is 1 cup' : 'are ' + pot.cups_left.to_s + ' cups'
         puts "There #{cup_string} of coffee left."
      end
   end
end

stick_figures = [
   CoffeeDrinkingStickFigure.new(:name => 'Miss Piggy', :sex => StickFigure::FEMALE),
   CoffeeDrinkingStickFigure.new(:name => 'Bert'),
   CoffeeDrinkingStickFigure.new(:name => 'Kermit', :is_lazy => true),
   CoffeeDrinkingStickFigure.new(:name => 'Ernie', :is_lazy => true)
]

stick_figures.each do |stick_figure|
   stick_figure.introduce_self
   stick_figure.have_coffee
end

Posted in , , | Tags , ,