my $name1 = ''; my $name2 = ''; my $address1 = ''; my $address2 = ''; ...

Novice programmers often seem to think that their biggest problem is learning the syntax of the language. Throw in the standard libraries, if you like. They're wrong, but that's okay -- they're novices. Their biggest problem is learning how to manage complexity. I've seen far too few tutorials teach this from the start. I believe that Perl 5 offers several excellent ways to manage complexity, and a handful of awful ways to allow complexity to spiral out of control. I also believe that a well-taught student will develop habits to prevent unnecessary complexity from creeping into a system. Let me be more concrete. Many novice programs I've read have big blocks of variable declarations at the top:

While that's technically a valid program (the computer doesn't care), it's probably not a well-abstracted or well-encapsulated program, and it's likely ignoring modern Perl idioms.

One of the greatest advantages of lexical scoping with enforced variable declarations -- an advantage Perl has over Ruby and Python, for example -- is that you can see the scope of a variable by looking for its declaration. If you keep your scopes small -- if you encapsulate behavior into discrete pieces -- you reduce the possibility that essential information will leak out of those scopes into surrounding code. You minimize the coupling between distinct units of behavior.

Try explaining that to a novice.

To my mind, the greatest discovery in programming is the procedure. Attaching a name to a discrete unit of behavior lets you break down a big problem into smaller problems. Lisp and Forth hackers talk about this all the time. So do functional programmers. It's true.

Try explaining that to a novice, too.

If we really believed that maintainability is the primary concern of code, and efficiency and reuse and optimization were second-order concerns, we'd explain subroutines as "a way to attach a name to a discrete unit of behavior" instead of "common code you call more than once." They're both largely true definitions, but explaining the former first confers a huge advantage in my mind. Get novices in the habit of breaking problems down into separate, named steps and perhaps they'll write better code.