A Ruby Serenade for 99 Bottles of Beer

A Ruby Serenade for 99 Bottles of Beer

Hello, budding Ruby enthusiasts! 🌟

Have you ever heard of the song 99 Bottles of Beer on The Wall? It's the kind of catchy tune that’s perfect for passing time with friends or family as you cruise down the vast stretches of highways in the US or Canada. With its repetitive melody and simple lyrics, it sticks in your head whether you want it to or not.

I first stumbled upon a quirky connection between this earworm and coding a few years back, thanks to Sandi Metz's enlightening talk at a Ruby conference. Sandi, a maestro of clean, maintainable OOP designs, has a knack for spinning traditional teaching methods on their head. Her approach is as refreshing as a cold brew on a hot day, and if you're a programmer aiming to sharpen your skills, her videos—courtesy of the splendid folks at Confreaks—are a treasure trove.

Sandi's fondness for the "99 Bottles" ditty isn't just for kicks; she's leveraged its repetitive charm to unravel the intricacies of OOP (Object-Oriented Programming). And yes, she's even authored a book, aptly titled 99 Bottles of OOP, which I'm thoroughly enjoying and heartily endorse.

Today's session isn't about vocal ranges or hitting the perfect pitch, although I'm sure you have a lovely voice and I'd not stop your karaoke party 🎙️. Instead, we're diving into a melody that echoes through the halls of coding exercises: "99 Bottles of Beer." This classic tune is a programming pilgrimage, and for Ruby enthusiasts, it's a delightful way to tinker with loops, conditionals, and OOP concepts. By the end of this post, you'll have a new party trick to show off at your next developer meetup.

🎯 The Goal

Imagine a wall lined with 99 bottles of beer. The song counts down each bottle as it's "taken down and passed around," until there are none left, then it's time to buy some more. Our mission, should we choose to accept it, is to write a Ruby script that sings this song from start to finish.

🛠️ Prerequisites

Before we start crooning in code, make sure you have:

  • A sprinkle of Ruby syntax knowledge.

  • Ruby, gleaming and ready on your machine.

  • A text editor, like VS Code, Atom, or even Notepad.

Got everything? Superb! Let's get coding!

Step 1: Comprehending the Composition

Our song has a repetitive structure, perfect for a loop. But, there's a twist! When we reach 1 bottle, we can't say "bottles" anymore—English is picky like that. And when there are no more bottles, the song changes its tune. Check out part of the lyrics below, and pay attention to the last three sections.

99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall.

98 bottles of beer on the wall, 98 bottles of beer. Take one down and pass it around, 97 bottles of beer on the wall.

... ... ... ... ...

2 bottles of beer on the wall, 2 bottles of beer. Take one down and pass it around, 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer. Take one down and pass it around, no more bottles of beer on the wall.

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.

Step 2: Setting the Stage

Create a new file named ninety_nine_bottles.rb. This will be our stage for the performance. To run it, we'll use the command line charm:

ruby ninety_nine_bottles.rb

Ready for the spotlight? Let's go!

Step 3: The Loop of Lyrics

Ruby has a beautiful way to count down with downto. It's like a staircase from 99 to 0:

99.downto(0) do |i|
  # This is where the magic happens...
end

Inside this loop, we'll call forth our verses.

Step 4: A Methodical Melody

Singular and plural bottles need different words. Let's tune our method to handle that:

def print_bottle(number)
  case number
  when 0  
      "no more bottles"
  when 1 
      "1 bottle"
  else
      "#{number} bottles"
  end
end

This method serenades us with the right words for each number.

Step 5: Verses in Verse

Now, the print_verse method will print each verse based on the number of bottles:

def print_verse(number)
  if number.positive?
    puts "#{print_bottle(number)} of beer on the wall, #{print_bottle(number)} of beer."
    puts "Take one down and pass it around, #{print_bottle(number-1)} of beer on the wall.\n\n"
  else
    puts "No more bottles of beer on the wall, no more bottles of beer."
    puts "Go to the store and buy some more, 99 bottles of beer on the wall.\n\n"
  end
end

Our loop now calls print_verse, making the song unfold:

99.downto(0) { |i| print_verse(i) }

Step 6: Refining the Rhapsody (Optional)

As our code croons perfectly, can we make it more elegant? Refactoring is like poetry editing—it's an art. Look at your code and ask, "Can I make this clearer? More Ruby-esque?" Don't worry if this step seems tricky—it comes with practice!

Step 7: The Grand Finale

Run your Ruby script and watch as the verses dance on your screen. It's a sing-along in text!

🖥️ Peek at My Code

Before we reach our coding crescendo, if you're itching to see a finished version or need a little inspiration, check out my solution on GitHub.

🧩 Share Your Rendition

Now, it's your turn to take the stage! How would you serenade the "99 Bottles of Beer" tune in Ruby? Everyone has their unique coding style, and I'd love to hear your verses. Share your approach to solving this problem by adding your solution to the 99 Bottles of Beer Ruby Challenge repo. Let's see how many variations we can compile from our creative community. Here’s how you can participate:

  1. Fork the repository.

  2. Add your solution to the repository in a new directory named after your GitHub username.

  3. Commit your changes and push them to your fork.

  4. Submit a pull request with your solution.

It's a fun way to get involved in open source and to see your code alongside solutions from other developers. Plus, it's a great addition to your coding portfolio!

🎤 Encore

Now that you've automated a song, learned some Ruby, and maybe even contributed to an open-source project, it's time to take a bow. Remember, programming is as much about community and sharing as it is about solving problems.

📚 Further Learning

If you enjoyed this, check Sandi's other book about Practical Object-Oriented Design, and explore more with Ruby's documentation and Rails guide for your next symphony.

Until next time, keep coding to the rhythm of your heart's beat, and let Ruby be your muse! 💎💻

Did you find this article valuable?

Support Ahmed Nadar by becoming a sponsor. Any amount is appreciated!