Language Ruby
(Using continuations, singleton classes)
Date: | 09/15/06 |
Author: | Victor Borja |
URL: | n/a |
Comments: | 9 |
Info: | http://www.ruby-lang.org |
Score: | ![]() |
# 99 Bottles of beer, in Ruby # By Victor Borja, Sep 14, 2006 # This one shows my favorite Ruby features: # continuations, open classes, singleton classes, blocks and being funny! class Integer # The bottles def drink; self - 1; end end class << song = nil attr_accessor :wall def bottles (@bottles.zero? ? "no more" : @bottles).to_s << " bottle" << ("s" unless @bottles == 1).to_s end def of(bottles) @bottles = bottles (class << self; self; end).module_eval do define_method(:buy) { bottles } end self end def sing(&step) puts "#{bottles.capitalize} of beer on the wall, #{bottles} of beer." if @bottles.zero? print "Go to the store buy some more, " step = method :buy else print "Take one down and pass it around, " end @bottles = step[@bottles] puts "#{bottles} of beer on the wall." puts "" or wall.call unless step.kind_of? Method end end callcc { |song.wall| song.of(99) }.sing { |beer| beer.drink }
Download Source | Write Comment
Alternative Versions
Version | Author | Date | Comments | Rate |
---|---|---|---|---|
object-oriented version | Mike Gertz | 04/20/05 | 2 | ![]() ![]() |
minimal version | Anonymous | 05/18/05 | 3 | ![]() ![]() |
shows inheritance, iterators, yield, etc | Kian Wright | 06/10/05 | 0 | ![]() ![]() |
alternative version | Greg T. | 05/18/05 | 10 | ![]() ![]() |
In words | Daniel Straight | 07/10/06 | 1 | ![]() ![]() |
wall-based OO version | Kevin Baird | 07/07/05 | 2 | ![]() ![]() |
monkeypatch and anonymous procs | J. B. Rainsberger | 04/04/07 | 0 | ![]() ![]() |
Readably re-opening Integer, teetotaller | Eric Budd | 01/06/08 | 0 | ![]() ![]() |
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!
Comments
The part I liked the more was the last line, especially "}.sing {", that makes use of a not commonly known behavior of ruby continuations. When the continuation is called the first time, the #sing message is sent to the value resulting from the body of callcc, however subsequent calls to the continuation (by means of wall.call) always send the #sing message to the nil object. I proved this by changing "song = nil" to "song = Object.new", now I understand why Victor used nil as the song, a very cleaver choice !.
I actually think I'll submit it.
(1..99).to_a.reverse.each do |bottle|
if bottle > 1
puts "#{bottle} bottles of beer on the wall, #{bottle} bottles of beer."
suffix = bottle > 2 ? "#{bottle -1} bottles of beer on the wall" : "1 bottle of beer on the wall"
elsif bottle == 1
puts "1 bottle of beer on the wall, 1 bottle of beer."
suffix = "no more beer on the wall!"
end
puts "Take one down, pass it around #{suffix}"
puts "--"
end
Nice codes.
num_bot = proc { |n| "#{n} bottle#{n == 1 ? '' : 's'}" }
99.downto(2) do |num|
puts "#{num_bot[num]} of beer on the wall, #{num_bot[num]} of beer!"
puts "Take one down, pass it around, #{num_bot[num-1]} of beer on the wall!"
end
puts "#{num_bot[1]} of beer on the wall, #{num_bot[1]} of beer!"
puts "Take one down, pass it around, no more bottles of beer on the wall!"
bob = proc { |num| "#{num == 0 ? "no more" : num} bottle#{"s" if num != 1} of beer" }
bob_on_wall = proc { |num| "#{bob[num]} on the wall" }
99.downto(1) {|f| print "#{bob_on_wall[f]}, #{bob[f]}!\nTake one down, pass it around, #{bob_on_wall[f-1]}!\n\n" }
puts <<END
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
END
# I prefer clear ruby code thought
def b i,w=nil;"#{i==0&&"no more"||i} bottle#{"s"if i!=1} of beer#{" on the wall"if w}"end
99.downto(1){|i|puts"#{b i,1}, #{b i}.\nTake one down, pass it around, #{b i-1,1}.\n\n"}
puts b(0,1).capitalize+", #{b 0}.\nGo to the store and buy some more, #{b 99,1}."