When I taught myself to program, I learned a functional language, in no small part because the language that I was learning was not object oriented. After some time, my code was starting to turn into spaghetti, so I started enforcing a rule where I put functions that operated on like data in separate files, and created abstractions so in my primary program flow I could work at a high level to keep things clean and understandable. When I was taught about objects they weren't very easy to understand, but when I connected the dots and saw it was what I was already doing, plus state, it all came together. I don't think that most educators do a good job explaining how OOP can really help you, they just start rambling about re-usability and polymorphism. I knew how to program, so I could understand why you would want these things, but to a newcomer they must seem meaningless and unapproachable.

If I were teaching, I wouldn't start new programmers with OOP, but I would bring them there quickly. Imagine an assignment where you have the students model a car, a stop sign, and a traffic light, and their interactions on a closed course. I'd have the students model the interactions using ruby hashes (e.g. car = {:color => 'blue', :state => 'stopped', :stop_time_required => 1}, traffic_light = {:color => 'red', :stop_time_required => 30}), and a series of functions for the first assignment, where the program prints what happens as it encounters a pre-defined course. This should result in some pretty crappy spaghetti code. For the next assignment, I'd have them clean up the structure of the program, separating the code into logical units based on what the code is operating on, a car, a red light, a stop sign. Lastly, I'd introduce OOP and have them update the code for OOP. It should take a lot less code to do the same thing, and it should be a lot cleaner. Polymorphism can be addressed by instructing the students that red light and stop sign are both traffic control devices, and having them implement to_s on each class to clean up their string handling code.

OOP can make lots of sense when it's presented as a time saving measure. However, especially in Java classes, it tends to start will a wall of code thirty lines long to print "Hello World", with the direction to ignore everything else. It would probably be better to start simple, with a 1 line program (e.g. puts 'Hello World'), and work up from there. That's not to say Ruby is the right language, it's probably a good starter language, but a strictly typed lower level language would probably be better once they get the hang of things. The beauty of ruby is that you can create useful code quickly, but you still need to be able to understand what's going on under the hood.

The two classes I learned the most from were a digital hardware class, and a assembly course. In the hardware course, the professor gave me a FPGA to work with after he saw I understood digital logic very well, and on that FPGA I implemented a basic instruction set, including jump, which could be entered using toggle switches, executed using a push button, with results output to a lcd. In the assembly course, the professor spent a great deal of effort manually compiling c to assembly, and explaining why. He was on the ANSI-C committee, and worked full time writing assembly for spacecraft at NASA, so offered a very unique prospective, and quite a bit of insight.