6.4 PrivacySymbols in Perl are freely accessible; privacy is not enforced. The online documentation says, rather colorfully, "Perl does not enforce private and public parts of its modules as you may have been used to in other languages like C++, Ada, or Modula-17. Perl doesn't have an infatuation with enforced privacy. It would prefer that you stayed out of its living room because you weren't invited, not because it has a shotgun."[ 2 ]
In addition to accessing a foreign package's existing variables or subroutines, a package can easily create new names in another package's namespace, as we saw earlier. Consider package Test; # Create a variable subroutine and subroutine in another package $main::foo = 10; sub main::myFunc { print "Hello \n"; } package main; myFunc(); # prints "Hello" Although this is not a very kosher thing to do in a normal application, this facility can be put to good use if applied in a controlled manner. You can use it to import foreign package symbol names into your own namespace; we will study this in the next section. 6.4.1 Enforcing PrivacyYou can use the my operator at file scope to get unassailably private variables. Because they are not associated in any way with a package, they cannot be accessed from a different scope (in this case, file scope). But because they don't have anything to do with packages, they are restricted at most to file boundaries. Consider package A; my $a = 10; # A lexical variable package B; print $A::a; # No such variable in package A print $a; # prints 10, because it can see the lexical variable # (even though package B is in effect) What if you want to make a subroutine name private? You cannot use my to declare a private subroutine, but you can use anonymous subroutines and hold references to them in lexical variables: my $rs_func = sub { .... }; Now, $rs_func can be dereferenced from within that scope (if it is a global variable anywhere within that file), but it cannot be accessed in another file. Whenever you want to call this function, you can either say &$rs_func or, if you intend to call it a number of times, use typeglob aliasing for convenience and efficiency: { local (*func) = $rs_func; for (1..100) {func()}; } While you can hide your own global identifiers, there's nothing you can do to prevent another module from installing new names into your namespace. In fact, older Perl libraries took this liberty a lot more. (Look at the bigint.pl package in the standard Perl library, for example.) Copyright © 2001 O'Reilly & Associates. All rights reserved. |
|