10.6. Bringing Some Closure

Understanding how lexical variables work is worth the effort. Suppose you have advanced to the stage of understanding closures—give yourself a pat on the back—and you decide to code a few subroutines that use a private variable that way:

   {
   my $protocol = "ftp";  # default

   sub get_proto
      {
      return $protocol;
      }
   sub set_proto
      {
      $protocol = shift;
      }
   }  # End of block containing closures

print get_proto();

(We've removed anything not necessary to understanding this point.) If you run this, you'll see that it indeed knows what the default protocol is, and you've successfully isolated that shared variable to the two subroutines that use it.

Let's say that later you decide that the subroutines are better off declared at the end of the file so that you can start reading with your main program—Perl can handle forward references, right? So you change it to

print get_proto();
   {
   my $protocol = "ftp";  # default
   sub get_proto
      {
      return $protocol;
      }
   sub set_proto
      {
      $protocol = shift;
      }
   }  # End of block containing closures

But now when you run the program, get_proto will complain about an uninitialized variable. The reason is closely related to our previous error: when we call get_proto in the first line, $protocol hasn't been initialized because we haven't gotten to the line where that happens yet. The reason there's no complaint from strict about it being an undeclared variable in the closures is that it has been declared; however, that happened at compile time, and the assignment of the default value won't happen until run time.

You can avoid this problem naturally by following Perl of Wisdom #18. If you don't yet understand closures but you're intrigued, read “What's a closure?” in the core Perl documentation section perlfaq7.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset