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!
`93113537’ could not be displayed because:
Photo not found
Photo not found
#
# 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
I think the real problem is that the pot is only 2.5 cups. A larger pot would allow for a lazier workforce. This small one puts a strong demand on the set.
well you know, programming examples never match the real-world requirements :-)