Voting

Category

real language

Bookmarking

Del.icio.us Digg Diigo DZone Earthlink Google Kick.ie
Windows Live LookLater Ma.gnolia Reddit Rojo StumbleUpon Technorati

Language Ruby

(shows inheritance, iterators, yield, etc)

Date:06/10/05
Author:Kian Wright
URL:n/a
Comments:0
Info:n/a
Score: (3.00 in 28 votes)
# 99 bottles of beer, in Ruby
# illustrates inheritance, blocks/yield, class methods, arrays, iterators
# Kian Wright

class Song
	def Song.sing(fridge)
		sing_how_many(fridge, :on_the_wall)
		sing_how_many(fridge, :nowhere)
		yield
		sing_how_many(fridge, :on_the_wall)
		puts
	end
	
	def Song.sing_how_many(fridge, where=:on_the_wall)
		puts "#{fridge.to_s} of beer #{where == :on_the_wall ? 'on the wall' : ''}"
	end

end

class Beer
	def drink(from=nil)
		from.delete(self) if from && from.respond_to?(:delete)
		puts "take one down and pass it around"
	end
end	
	
class Beers < Array
	def drink(how_many=length)
		how_many = length if how_many == :all
		
		self[0,how_many].each do |beer|
			Song.sing(self) { beer.drink(self) }
		end
	end

	def restock(how_many)
		Song.sing(self) { buy(how_many) }
	end
		
	def buy(how_many)
		fill(0, how_many) { Beer.new }
		puts "go to the store and buy some more"
	end
	
	def to_s
		case length
		when 0
			"no more bottles"
		when 1
			"one bottle"
		else
			"#{length} bottles"
		end
	end
end

fridge = Beers.new(99) {|i| Beer.new }
fridge.drink(:all)
fridge.restock(99)

Download Source | Write Comment

Alternative Versions

VersionAuthorDateCommentsRate
Using continuations, singleton classesVictor Borja09/15/069
In wordsDaniel Straight07/10/061
alternative versionGreg T.05/18/0510
minimal versionAnonymous05/18/053
object-oriented versionMike Gertz04/20/052
wall-based OO versionKevin Baird07/07/052
monkeypatch and anonymous procsJ. B. Rainsberger04/04/070
Readably re-opening Integer, teetotallerEric Budd01/06/080

Comments

Download Source | Write Comment

Add Comment

Please provide a value for the fields Name, Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.

Please don't post large portions of code here! Use the form to submit new examples or updates instead!

Name:

eMail:

URL:

Security Code:
  
Comment: