Making Functions Private to a Module (Perl Cookbook, 2nd Edition)

## 12.5. Making Functions Private to a Module

### 12.5.1. Problem

You want to make a function private to a package.

### 12.5.2. Solution

You can't. But you can make a private variable and store a reference to an anonymous function in it.

>     # this is the file SomeModule.pm
>     package Some_Module;

>     my $secret_function = sub {
>         # your code here
>     };

>     sub regular_function {
>         # now call your "private" function via the code ref
>         $secret_function->(ARG1, ARG2);
>     }

### 12.5.3. Discussion

Even a function that isn't exported can still be accessed by anyone, anywhere if they qualify that function's name with its package. That's because function names are always in the package symbol table, which is globally accessible.

By creating a lexical variable at the file scope, code in that module file below the point of declaration has full access to that variable. Code in other files will not, because those scopes are unrelated. The subroutine created via `sub { ...`. `}` is anonymous, so there's no name in the symbol table for anyone outside to find. Not even other code in the module can call the function by name, since it doesn't have one, but that code can use the lexical variable to dereference the code reference indirectly.

>     $secret_function->(ARGS);                # infix deref form
>     &$secret_function(ARGS);                 # prefix deref form

Curiously, if you really wanted to, you could give this anonymous function a temporary name. Using the technique outlined in Recipe 10.16, assign the code reference to a localized typeglob, like this:

>     sub module_function {
>         local *secret = $secret_function;
>         Other_Package::func1( );
>         secret(ARG1, ARG2);
>         Yet_Another_Package::func2( );
>     }

Now for the duration of `module_function`, your previously secret function can be called using a direct function call; no indirection required. However, code outside the module can also find that function. In the example, it doesn't matter whether `func1` and `func2` are in the module's file scope, because you've made a temporary symbol table entry through which they could get at your secret function. Therefore, if `Other_Package::func1` turned around and called `Some_Module::secret`, it could find it—but only if `func1` were called from the `module_function` in the example. If it were called from some other point, there wouldn't be any `secret` function in the Some_Module package symbol table, so the attempted function call would fail.

This slightly peculiar behavior, where temporaries' values and visibility depend upon who called whom at runtime, is called dynamic scoping. This is the nature of the `local` keyword. You can see why we don't usually suggest using it.

### 12.5.4. See Also

Recipe 12.4; the section on "Dynamically Scoped Variables: local" in Chapter 4 of Programming Perl; the section on "Symbol Tables" in Chapter 10 of Programming Perl

Copyright © 2003 O'Reilly & Associates. All rights reserved.