On Sun, Mar 1, 2009 at 12:23 PM, Zayd Abdullah <devrubygem / gmail.com> wrote: > Thanks Justin. > So the reason bottles_of_beer is attr_accessor is because I have to access > it to change the value of it, and bottle_word and one_word are attr_readers, > because those values never change? > > Here goes my new code that worked just fine > > class Bottles > > attr_accessor :bottles_of_beer > > attr_reader :bottle_word, :one_word > > def initialize(bottles_of_beer, bottle_word, one_word) > @bottles_of_beer = bottles_of_beer > @bottle_word = bottle_word > @one_word = one_word > > end > > end > > > my_bottles = Bottles.new(99, 'Bottles', 'Bottle') > > while my_bottles.bottles_of_beer >= 2 > puts "#{my_bottles.bottles_of_beer} #{my_bottles.bottle_word} of beer on > the wall" > puts "#{my_bottles.bottles_of_beer} #{my_bottles.bottle_word} of beer" > puts "Take one down, pass it around" > > my_bottles.bottles_of_beer -= 1 > > if my_bottles.bottles_of_beer == 1 > puts "#{my_bottles.bottles_of_beer} bottle of beer on the wall" > > else > puts "#{my_bottles.bottles_of_beer} #{my_bottles.bottle_word} of > beer on the wall" > > end > > > if my_bottles.bottles_of_beer == 1 > puts "#{my_bottles.bottles_of_beer} #{my_bottles.one_word} of beer > on the wall" > puts "#{my_bottles.bottles_of_beer} #{my_bottles.one_word} of beer" > puts "Take one down, pass it around" > > my_bottles.bottles_of_beer -= 1 > > puts "No more #{my_bottles.bottle_word} of beer on the wall" > > > > > end > > > end Just to explore the language a bit... module Grammar Noun = Struct.new( :singular, :plural, :collective ) end include Grammar bottleness = Noun.new( "bottle", "bottles", "case" ) 10.downto(1) do |i| puts("#{i} #{i == 1 ? bottleness.singular : bottleness.plural} of beer on the wall") end ...of course you'd need to add the other phrases of the sing/song in there. Why a module? I guess it just seemed to make sense at the moment. Why a Struct? Because it builds accessors for me automatically. In reality, I'd try to separate the execution code from the string phrases (I pretty much try to avoid the #{} as much as I can). One thing interesting I should mention, though, is that the #{} construct can be used to not only display variable values, but also method results, and even expressions, so... 99.downto(1) do |i| suffix = (i == 1 ? '' : 's') puts "#{i} bottle#{suffix} of beer on the wall," puts "#{i} bottle#{suffix} of beer," puts "Take one down pass it around," puts "#{i-1} bottle#{'s' unless i == 2} of beer on the wall.\n" #that last line actually works puts end ...simple method example... def foo 'hi' end puts "{#foo} there" ...but, like I said. Finding a way to separate static data from logical data is usually the best route for good code (which I have _not_ done in the above examples). And don't forget for that last edge case, namely, "No more" for zero. hth, Todd