Perl Programming Page 2 - Understanding Scope and Packages in Perl |
When we start programming, we’re in a package called main. A package is a collection of variables that is separate from another package. Let’s say we have two packages: A and B. Each package can have its own variable named$x, and those two$xvariables are completely distinct. If we assign$x, as we did previously inglobal2.pl, then we create a package variable$xin packagemain (themainpackage is the default package). Perl knows it by its full name,$main::x—the variable$xin themainpackage—but because we’re in themain package when we make the assignment, we can just call it by its short name,$x. It’s like the phone system— you don’t have to dial the area code when you call someone in the same area as you.1 1. Depending on your location, of course. Nowadays, with so many area codes in a metropolitan area, to call across the street often requires dialing 10 digits . . . We can create a variable in another package by using a fully qualified name. Instead of the main package, we can have a package calledFred. Here we’ll store all of Fred’s variables and subroutines. So, to get at the$namevariable in packageFred, we say$Fred::name, like this: $x = 10; The fact that it’s in a different package doesn’t mean we can’t get at it. Remember that these are global variables, available from anywhere in our program. All packages do is give us a way of subdividing the namespace. What do we mean by “subdividing the namespace”? Well, the namespace is the set of names we can give our variables. Without packages, we could only have one$name. What packages do is help us make$namein packageFreddifferent to$namein packageBarneyand$namein packagemain. #!/usr/bin/perl -w $main::name = "Your Name Here"; $Fred::name = "Fred Flintstone"; $Barney::name = "Barney Rubble"; print "\$name in package main is $name\n"; print "\$name in package Fred is $Fred::name\n"; $ perl globals1.pl You can change what package you’re currently working in with the aptly namedpackageoperator. We could write the preceding like this: #!/usr/bin/perl -w $main::name = "Your Name Here"; print "\$name in package main is $name\n"; package Fred; print "\$name in package Fred is $name\n"; package Barney; print "\$name in package Barney is $name\n"; package main; Whenuse strict is in force, it makes us use the full names for our package variables. If we try and say this: #!/usr/bin/perl -w use strict; $x = 10; Perl will give us an error—global symbol$xrequires an explicit package name. The package name it’s looking for ismain, and it wants us to say$main::x. #!/usr/bin/perl -w use strict; $main::x = 10; Global variables can be accessed and altered at any time by any subroutine or assignment that you care to apply to them. Of course, this is handy if you want to store a value—for instance, the user’s name—and be able to get it anywhere. It’s also an absolute pain in the neck when it comes to subroutines. Here’s why: $a = 25; Looks innocent, doesn’t it? Looks like we should see the answer 25. But what happens ifsome_sub()uses and changes the global$a? Any variable anywhere in your program can be wiped out by another part of your program—we call this action at a distance, and it gets real spooky to debug. Packages alleviate the problem, but to make sure that we never get into this mess, we have to ensure that every variable in our program has a different name. In small programs, that’s feasible, but in huge team efforts, it’s a nightmare. It’s far clearer to be able to restrict the possible effect of a variable to a certain area of code, and that’s exactly what lexical variables do.
blog comments powered by Disqus |
|
|
|
|
|
|
|