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

(Using continuations, singleton classes)

Date:09/15/06
Author:Victor Borja
URL:n/a
Comments:4
Info:http://www.ruby-lang.org
Score: (3.61 in 57 votes)
# 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

VersionAuthorDateCommentsRate
object-oriented versionMike Gertz04/20/052
In wordsDaniel Straight07/10/061
shows inheritance, iterators, yield, etcKian Wright06/10/050
Readably re-opening Integer, teetotallerEric Budd01/06/080
wall-based OO versionKevin Baird07/07/052
alternative versionGreg T.05/18/0510
minimal versionAnonymous05/18/053
monkeypatch and anonymous procsJ. B. Rainsberger04/04/070

Comments

>>  I like Ruby said on 01/13/07 01:31:44

I like Ruby This may not be the shortest and most efficent version, but it's defenitly the version with the most fun reading it.
Especialy the parts "wall.call" if you need the next bottle, "step = method :buy" if you have no beer left and "beer.drink" as what to do in each stanza.

I would actualy call it a geek poem.

For those of you who don't code Ruby: Learn Ruby, so you can enjoy reading this poem and writing your next scripts/applications/whatever.

>>  Pepe said on 01/19/07 20:33:48

Pepe Yeah men, keep doing the good work. How Deep is this men, it moves me to tears.

>>  rafa said on 01/25/07 18:49:34

rafa I really like this over the other versions, I think it shows more the ruby way.

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 !.

>>  Hesenrre said on 01/26/07 02:05:15

Hesenrre Jejejejeje, like your coding friend :D, ruby rules!!!!

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: