my $name1 = ''; my $name2 = ''; my $address1 = ''; my $address2 = ''; ...
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.