Private methods in Perl5

It is common knowledge that you can’t have private functions and methods in Perl5. But it turns out that you can do it, one way is to use namespace::clean. Using this module you can either declare all the names of private functions at the top or use a serie of non-obvious “use namespace::clean“, “no namespace::clean” calls.

Wouldn’t it be much nicer just to be able to write:


sub foo :Private {
    ...
}

You can, with my brand new Sub::Private module. It is actually quite simple:


use Attribute::Handlers;

use namespace::clean     qw();
use B::Hooks::EndOfScope qw(on_scope_end);
use Sub::Identify        qw(get_code_info);

sub UNIVERSAL::Private :ATTR(CODE,BEGIN) {
    my ($package, $symbol, $referent, $attr, $data) = @_;

    on_scope_end {
        namespace::clean->clean_subroutines( get_code_info( $referent ) );
    }
}

Putting the attribute handler in the UNIVERSAL namespace isn’t nice. I have to find a solution for that for the next version.

8 Comments »

  1. frew said,

    August 14, 2009 @ 5:03 pm

    You can also do private methods without any magic at all. Heres a super basic example:

    package Foo;

    my $private_foo = sub { print “private” };
    sub public_foo { my $self = shift; $self->$private_foo }

    1;

  2. chromatic said,

    August 14, 2009 @ 8:05 pm

    I’m not sure you get “private methods” with this approach. You won’t be able to invoke private subs as methods this way, as when the time comes to perform the lookup, the symbol is no longer available.

  3. Re: Private methods in Perl5 at Infinite Pig Theorem said,

    August 14, 2009 @ 11:37 pm

    [...] Peter, I have a single word for you: Moose. [...]

  4. Yuval Kogman said,

    August 15, 2009 @ 3:55 am

    In your test class your usage of private symbols is not as method lookups, but as function calls.

    $self->bar will not work, even from inside the Foo class where it should.

  5. phaylon said,

    August 15, 2009 @ 7:14 pm

    Btw, you probably want to use ‘namespace::clean’ last, after all your other imports. It will remove anything imported before it, and will leave anything after alone.

  6. phaylon said,

    August 15, 2009 @ 7:15 pm

    (last comment was of course meant in addition to your functional usage of it, if you load it, why not use it? :)

  7. ScholarshipAdvice said,

    August 21, 2009 @ 7:41 am

    This is great, at first I didn’t really know that I can do this but as i tried working on it and see what it does, i am so delighted that I was able to read your post and very satisfied about it….thanks…

  8. wolfgang said,

    September 9, 2009 @ 10:47 pm

    I haven’t tried this private functions and methods in Perl5 and I guess it will be a good thing for me to try it. Hopefully to see your next version.

RSS feed for comments on this post · TrackBack URI

Leave a Comment