|Perl: the Markov chain saw|
Go reinvent some wheels. I know that sounds like heresy, but there's a hell of a lot of value in reinventing the wheel.
To back up a little, let's repeat the three cardinal virtues of programming -- laziness, impatience and hubris:
Now let's turn them sideways and see how they become the three deadly sins of programming -- sloppiness, rushing and arrogance:
What does this have to do with programming every day? Well, what we're really talking about is exercise -- building your mental muscles and stretching your imagination so you're in top form when you need to solve a real problem.
You want to work like hell now, so you don't have to work as hard when the chips are down. With a little care, you can use that Laziness to cultivate Impatience and Hubris, too. But as with physical exercise, you'll be fighting Sloppiness, Rushing, and Arrogance every step of the way -- both in yourself and in others.
The real secret of excercise is that it's boring. The limit you really push is your ability to ignore a continuous stream of thoughts like, "I don't like this -- this sucks -- I want to stop," and keep working. That stream starts when you hit about 20% of your actual capacity, and keeps going until the endorphins kick in -- which happens in programming just as much as it happens in physical exercise.
If you learn to ignore the negative thoughts (and complaints of the people around you who don't even want to see someone working hard) long enough to feel the rush, you can be Lazy. If you let the negative thoughts stop you, you'll just end up being Sloppy.
So, with that sermon out of the way, the best thing you can do is go back and drill your fundamentals. Pick up a good reference on algorithms (_Introduction to Algorithms_, Cormen, Leiserson, and Rivest is very good) and build linked lists. Build circular lists. Build binary trees. Build heaps. Build hashes. Write sorting routines. Write code to implement basic data structures and algorithms, then go back and write it all again. And again. And again.
Think you know how to write a bubble-sort, Shell sort, Heapsort or quicksort? Think you can do it in one pass, without having to refer to any references? Don't think -- write them over and over until you know you can.
Then start working your way through the standard Perl library. Pick a file, and copy it -- and I don't mean <kbd>`cp /usr/lib/perl/Module_X.pm ~/My_module_X.pm`</kbd>. Transcribe it by hand, one character at a time, just so you can say you've read the thing down to the last punctuation mark.
Split out the interesting bits. Play with the techniques you discover. Find out what alternatives exist, and why the existing version is the best for any given situation. Stamp down your boredom until you understand the module well enough to implement it from scratch. Then find some Hubris and try to write something better.
That should be enough to keep you going for at least a decade or two.
Don't let people give you crap about wasting time, or doing things the hard way. You don't learn to solve hard problems by waiting for someone else to hand you packaged solutions. You learn by repeating what others have done before, and learning the sequence of thought that leads to the solution, not just the solution itself.
Walking the path is where you learn to think critically, and hone your problem-solving instincts. The fact that the problem has already been solved just keeps you from getting stuck forever in the diversions and dead ends.
If someone asks why you're "wasting time" reinventing the wheel, say, "so I can. Can you?"