I am working on a little Perl module and for some reason I had the test driver script that was using my new module call one of the functions that I thought would be private, and it was successful. I was surprised, so I started searching google and I couldn’t really find any documentation on how to make private functions in Perl modules…
I saw one place that said to put a semicolon after the closing brace of your ‘private’ function, like this:
sub my_private_function { ... };
I tried that, but my driver script could still access the function I wanted to be private.
I’ll make up something that will be a shorter example, but here’s what I’m after:
Module TestPrivate.pm:
package TestPrivate; require 5.004; use strict; use warnings; use Carp; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); require Exporter; @ISA = qw(Exporter AutoLoader); our @EXPORT_OK = qw( public_function ); our @EXPORT = qw( ); $VERSION = '0.01'; sub new { my ( $class, %args ) = @_; my $self = {}; bless( $self, $class ); $self->private_function('THIS SHOULD BE PRIVATE'); $self->{public_variable} = 'This is public'; return $self; } sub public_function { my $self = shift; my $new_text = shift; $self->{public_variable} = $new_text; print 'Public Variable: $self->{public_variable}\n'; print 'Internal Variable: $self->{internal_variable}\n'; } sub private_function { my $self = shift; my $new_text = shift; $self->{internal_variable} = $new_text; }
Driver: TestPrivateDriver.pl
#!/usr/bin/perl use strict; use TestPrivate 'public_function'; my $foo = new TestPrivate(); $foo->public_function('Changed public variable'); $foo->private_function('I changed your private variable'); $foo->public_function('Changed public variable again'); $foo->{internal_variable} = 'Yep, I changed your private variable again!'; $foo->public_function('Changed public variable the last time');
Driver output:
Public Variable: Changed public variable Internal Variable: THIS SHOULD BE PRIVATE Public Variable: Changed public variable again Internal Variable: I changed your private variable Public Variable: Changed public variable the last time Internal Variable: Yep, I changed your private variable again!
So I added a semicolon after the last closing brace in the module, but the output is still the same. The only thing I really found was to add this line as the first line to my private_function:
caller eq __PACKAGE__ or die;
But that seems pretty hacky. I don’t have a lot of experience writing Perl modules, so maybe I am setting my module up incorrectly? Is it possible to have private functions and variables in perl modules?
Thanks for helping me learn!
From
perldoc perltoot(about a quarter way through the document):Therefore, I recommend you put an underscore or two at the beginning of your ‘private’ methods to help dissuade usage.