Skip to content

Instantly share code, notes, and snippets.

@sofaking
Last active May 5, 2020 19:15
Show Gist options
  • Save sofaking/da4bfe5412c8a3ebc611d5c3accf5f48 to your computer and use it in GitHub Desktop.
Save sofaking/da4bfe5412c8a3ebc611d5c3accf5f48 to your computer and use it in GitHub Desktop.
"Translation" of Kent Back's 99 bottles of beer Smalltalk version: https://leftsideagile.com/index.php?post/2020/02/16/The-Beginning-of-Extreme-Programming
class Verse
attr_accessor :stream, :count
def self.verse(count, stream)
case
when count < 0 then NegativeVerse.new
when count == 0 then UltimateVerse.new(stream)
when count == 1 then PenultimateVerse.new(stream)
else PrecedingVerse.new(stream).tap { |pv| pv.count = count }
end
end
def self.sing(count)
stream = ''
verse(count, stream).sing
puts stream
end
def initialize(stream)
self.stream = stream
super()
end
def sing
sing_verse
next_verse.sing
end
def sing_verse
bottles_of_beer_on_the_wall
bottles_of_beer
take_one_down
next_verse_bottles_of_beer_on_the_wall
stream << "\n"
end
def bottles_of_beer_on_the_wall
count_bottles
stream << ' of beer on the wall '
end
def count_bottles
stream << bottle_count_string
stream << ' '
stream << bottles_string
end
def bottle_count_string
count.to_s
end
def bottles_string
'bottles'
end
def bottles_of_beer
count_bottles
stream << ' of beer '
end
def take_one_down
stream << 'Take one down and pass it around '
end
def next_verse_bottles_of_beer_on_the_wall
next_verse.bottles_of_beer_on_the_wall
end
def next_verse
self.class.verse(count - 1, stream)
end
end
class NegativeVerse
def sing
'Do nothing'
end
end
class UltimateVerse < Verse
def count
0
end
def bottle_count_string
'No'
end
def next_verse_bottles_of_beer_on_the_wall
bottles_of_beer_on_the_wall
end
def take_one_down
stream << 'There are no more to pass it around '
end
end
class PenultimateVerse < Verse
def bottles_string
'bottle'
end
def count
1
end
def take_one_down
stream << 'Take it down and pass it around '
end
end
class PrecedingVerse < Verse
def take_one_down
stream << 'Take one down and pass it around '
end
end
Verse.sing(99)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment