Trade-off between variable name descriptiveness and readabil

As a mentor of the new adopt-a-newbie system, which I think is going
excellently, I was reviewing a 99-bottles-of-beer method. We went over
what he had, what I thought could be better and I showed an example of
exactly how I would do it, which was this:

def sing_song(start)
start.downto(1) do |numBottles|
puts “#{numBottles.bottles} of beer on the wall,
#{numBottles.bottles} of beer!”
puts “Take one down, pass it around, #{(numBottles-1).bottles} of
beer on the wall”
puts
end
end

String#bottles just does “x bottle(s if needed).” Anyway, one could
further refine this code to be more english-y by changing numBottles to
num in the following way:

def sing_song(start)
start.downto(1) do |num|
puts “#{num.bottles} of beer on the wall, #{num.bottles} of
beer!”
puts “Take one down, pass it around, #{(num-1).bottles} of beer
on
the wall”
puts
end
end

I doing this, the code reads better but the variable’s name loses a lot
of its descriptiveness. What would all of you guys do? I was also
thinking of renaming the bottles method to disp, but that has the
potential to conflict with a lot of other things and doesn’t really
describe what the method does. I also considered putting
numBottles.bottles into a variable but it didn’t seem right.

Dan

Daniel F. wrote:

def sing_song(start)
start.downto(1) do |num|
puts “#{num.bottles} of beer on the wall, #{num.bottles} of
beer!”

I prefer num.bottles; it reads well.

On Feb 22, 2007, at 12:32 AM, Daniel F. wrote:

of beer on the wall"

puts "#{num.bottles} of beer on the wall, #{num.bottles} of beer!"

really describe what the method does. I also considered putting
numBottles.bottles into a variable but it didn’t seem right.

The second method above reads a little better to me than the first;
numBottles.bottles is repetitive. However, I don’t like “start,” and
I’d like to throw out “how_many” in place of “num”:

def sing_song(bottles_on_the_wall)
bottles_on_the_wall.downto(1).do | how_many |
puts “#{how_many.bottles} of beer on the wall, #
{how_many.bottles} of beer!”
puts “Take one down, pass it around, #{(how_many - 1).bottles}
of beer on the wall”
puts
end
end

What do you think?

Craig

On Thu, 2007-02-22 at 14:32 +0900, Daniel F. wrote:

beer on the wall"

puts

end
end

It should be “num_bottles” if nothing else! :wink:

Cheers,
Daniel

On Thu, 22 Feb 2007 06:32:26 +0100, Daniel F.
[email protected] wrote:

of its descriptiveness. What would all of you guys do? I was also
thinking of renaming the bottles method to disp, but that has the
potential to conflict with a lot of other things and doesn’t really
describe what the method does. I also considered putting
numBottles.bottles into a variable but it didn’t seem right.

Quoth Mr. Torvalds: ‘If you have some random integer loop counter, it
should probably be called “i”. Calling it “loop_counter” is
non-productive, if there is no chance of it being mis-understood.’

I’d go with that, and not putting a #bottles method into Integer - I
find
that more or less pointless. (Also, I consider open classes and use and
abuse thereof an advanced topic that’s better treated along with some
design.) That would make it rather abundantly clear from looking one
line
below what ‘i’ means, and I’ll submit that a newbie that can’t work with
at least sufficiently straightforward (i.e. no method chain of five
iterators) three lines of code in his head is beyond hope anyway.

David V.

On Feb 22, 4:58 am, “David V.” [email protected] wrote:

non-productive, if there is no chance of it being mis-understood.’

I’d go with that, and not putting a #bottles method into Integer - I find
that more or less pointless.
David V.

For actual classes, I should agree, but to teach a newbie, I’d go with
num.bottles or num_bottles, as they’re more explanative to keep track
of where did they come from, and what should they do.

Also, the implementation of the method depends on what are you
pretending to show (assuming it’s for teaching). If you want to show
the power of OO, I’d stick a #bottles method onto Fixnum; if you want
to show blocks, I’d go with a method that yields the number of bottles
(or the string “No more”); I think in this case, you should give more
than one option. For example, another way would be.

class Wall

attr_accessor :bottles

def initialize(bottles)
    @bottles = bottles
end

def to_s
    "the wall"
end

def sing
    "#{@bottles} of beer on #{self} .....

etc…

and analyze which solution is the best. A good exercise for your
traineé wold be select the best approach and state why it is so.

Just sharing my point of view.

Ruben.

99 programmers will have 99 different solutions, so here’s mine :wink:

BTW, I’m with David V.; make the loop index a short name and
decorate it another way. I’ve tried at the same time to make the DRY
concept sink in.

Make the singer look a bit intelligent :slight_smile:

def bottles(n)
case n
when 0
“no more bottles”
when 1
“1 lonely bottle”
else
“#{n} bottles”
end
end

def sing_song(starting_bottles)
starting_bottles.downto(1) do |n|
num_bottles = bottles(n)
puts “#{num_bottles} of beer on the wall, #{num_bottles} of beer!”
num_bottles = bottles(n - 1) # One down
puts “Take one down, pass it around, #{num_bottles} of beer on the
wall.”
puts
end
end

irb(main):047:0> sing_song 3
3 bottles of beer on the wall, 3 bottles of beer!
Take one down, pass it around, 2 bottles of beer on the wall.

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

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

My $0.02.