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:
- Laziness is what makes you work like hell to
automate some problem that could be solved by hand in less
time -- once. The investment pays off when you have to
solve the same problem a second time, though.
- Impatience is what makes you work like hell to
improve code that's 'good enough if you're already used to
it'. You could also call it a resolute decision not
to become used to 'good enough' code.
- Hubris is what makes you look at a piece of
mature code and think, "I could do it better." It's also
what makes you deliver on that bet.
Now let's turn them sideways and see how they become the three
deadly sins of programming -- sloppiness, rushing
and arrogance:
- Sloppiness is what makes you write worse code
than you could. When you cut a corner and think, "I should
really do X, but what the hell, it's not that important,"
you're being sloppy. Laziness means doing work yourself,
so other people don't have to. Sloppiness means making other
people work so you don't have to.
- Rushing is what makes you start coding before
you know what you're trying to do. It makes you write 500
lines of code that solve the wrong problem. It's what
causes 'shotgun debugging' -- chopping out a couple lines of
code here, changing a value there, and breaking things left
and right because you can't be bothered to spend five
minutes finding out what actually needs to be done.
Impatience moves you to improve code. Rushing moves you to
accept lousy code because it's here now.
- Arrogance is what makes you think you know it
all. It's what makes you hypnotize yourself into thinking
your pet solution is the exception to the Perl motto:
There's More Than One Way To Do It. Hubris means thinking
you can improve on something you know to be good.
Arrogance means thinking anything you don't like is crap.
The three cardinal virtues reinforce each other. Using one
prompts you to use the others. So do the three deadly sins.
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.
That's Laziness.
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?"