Mike Vezzani <lists / ruby-forum.com> wrote:
> Hello all,

Hi, Mike, welcome to the wonderful world of Ruby!

> I'm a 6 month newbie to the Ruby programming language. I've been
> hesitant in the past to participate in the ruby community simply because
> I feel my knowledge and experience is lacking, but I have been
> encouraged by the numerous sources that have said that the ruby
> community is open and friendly, so I'm giving this a try.

Good-o!

> My project of the day is to design a simple Cabinet class. I've attached
> what code I have written thus far.
> 
> The end goal of this project is to create a simple cabinet object that
> has three drawers that can have objects placed into or removed from
> them. Also, I hope to write methods that would allow me to generate a
> report of what objects are in which drawers as well as inquiry methods
> that would establish whether a particular drawer was full or empty.
> 
> I'm struggling with understanding how to place things in each drawer
> such that when I consider what code to write to retrieve those items, I
> am stumped. Does the problem lie in the fact that I haven't considered
> that the drawers are their own objects as well, and I need to figure out
> how to make multiple objects interact with one another to create a
> functioning virtual cabinet?
> 
> While sample code that would create a functioning Cabinet class is
> appreciated, I feel that my lack of understanding doesn't simply stem
> from the fact that I don't know the exact code, but rather that I do not
> understand a more general concept of ruby programming. Explanations that
> would help with this would be appreciated. Thanks!

I think others have given you a good lead in terms of building classes
and associated data structures. I'm going to discuss something
else. That is separation of logic, data and presentation (the latter in
this case being your user interaction).

Structuring your classes deals with the logic and data of your
program. What struck me, though, was this:

  def place
    #a method to place an object in a drawer
    puts "What would you like to put into the cabinet?"
    thing = gets.chomp
    puts "What drawer number would you like to place #{thing} in? One, two, or three?"
    drawer_number = gets.chomp.downcase
    case drawer_number
    when 'one'
      puts "#{thing} has been placed in drawer one."
    when 'two'
      puts "#{thing} has been placed in drawer two."
    when 'three'
      puts "#{thing} has been placed in drawer three."
    else
      puts "I'm sorry, please select from one, two, or three."
    end
    
  end

You Cabinet class and it's containers and so on would ideally be
completely free of the machinations of getting the things to put in the
drawers. By mixing in the user interaction, you are making your class
much less usable for other projects. Realizing this is a kata, one of
the tenets of good practice is to follow more strict rules. "Wax on, Wax
off. Up and Down." :)

So a better approach is to make your Cabinet class's methods as slim and
simple as possible, using some of the techniques others have shown. The
other huge advantage to this is that it makes your classes much much
easier to test. While doing this interactively seems easy, doing it
every time you make a change gets quite tedious. Having a set of tests
at hand makes things much faster.

The other thing is that writing tests really helps in solidifying what
you want your class to do and how it should behave from an external
point of view. 

There are several test frameworks, but as you're really in the beginning
stages, you might find them daunting (not that I want to discourage you
from looking!). But the simplest test is just a ruby script that calls
your classes with set values and makes sure they all work the way you
expect them to. Liberal use of puts will help.