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