Created
December 6, 2013 17:42
-
-
Save jmccartie/7829015 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Beer | |
attr_accessor :bottle_count | |
def sing(first, last=0) | |
first.downto(last).inject("") do |memo, num| | |
memo << verse(num) + "\n" | |
end | |
end | |
def verse(num) | |
@bottle_count = num | |
[line1, line2, action, remaining_bottles].join() | |
end | |
private | |
def line1 | |
pluralize_bottles(bottle_count).capitalize + " of beer on the wall, " | |
end | |
def line2 | |
pluralize_bottles(bottle_count) + " of beer.\n" | |
end | |
def action | |
if bottle_count == 0 | |
"Go to the store and buy some more, " | |
else | |
"Take #{humanize_bottles} down and pass it around, " | |
end | |
end | |
def remaining_bottles | |
reset_bottles if bottle_count == 0 | |
"#{pluralize_bottles(bottle_count-1)} of beer on the wall.\n" | |
end | |
def reset_bottles | |
@bottle_count = 100 | |
end | |
def humanize_bottles | |
bottle_count == 1 ? 'it' : 'one' | |
end | |
def pluralize_bottles(count) | |
if count == 0 | |
"no more bottles" | |
elsif count == 1 | |
"1 bottle" | |
else | |
"#{count} bottles" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What's cool about the approach in https://gist.github.com/danielmurphy/7827772 is that it is easy to extend. To change verse 6 ("A 6 pack of beer on the wall..."), there is no code that has to change, you just create a new class (BeerSongVerse6).
Conceptually the goal is to find and use the correct object that with a very small scope, instead of one object that knows lots.
A code smell to look for is several if statements. That is a clue that there are probably multiple responsibilities stuffed into one object type.