Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to organize private methods on Perl objects?

Tags:

oop

perl

What is the correct way to handle methods which will not be called by the user? For example if the user calls a method, say do_stuff() from a driver script, and if do_stuff() relies on other subroutines, is it best practice to call those subs from within the do_stuff() method as follows:

sub do_stuff {
    my ( $self, %arg ) = @_;
    #does it things
    #and then calls the private sub as follows
    _private_sub( $self, %arg );
}
like image 762
Haloor Avatar asked Jan 04 '23 19:01

Haloor


2 Answers

To my knowledge, there's no "correct" way. Perl doesn't provide the ability to hide the functions, at least that I've ever run across. What I've done is use a naming standard where I start the internal-only function names with an underscore and clearly document that they're never to be called by external callers.

EDIT: The other answers triggered a thought. In each private method, you could check the results of the "caller ()" function and abort if the caller is anyone other than the local module. Honestly, I personally wouldn't go to the trouble, but if it's really important to you for some reason, that would emphasize the private nature of these methods.

like image 179
goug Avatar answered Jan 07 '23 09:01

goug


If your do_stuff method needs the functionality that you decided should be kept "private" then by all means call _private_sub within it. That is precisely its purpose. Of course, having a sub be "private" is a matter of convention as it cannot be enforced.

I'd like to mention another way, of using coderefs for private subs

my $_private = sub { ... };  # must be at least predeclared

sub do_stuff {
    my ($self, %arg) = @_;
    # ...
    my $from_private = $self->$_private->(@args);    # or
    my $more_private = $_private->($self, @args);
}

The syntax is odd but that surely warns the users that it is a private method. This makes it hard for subclasses to inherit, thanks to mob for emphasizing this.

The second invocation uses $_private as a function rather than a method, so we have to pass the object if it needs it. This further warns against its use. Then it also doesn't undergo the normal method lookup process (and is thus slightly faster), something to be well aware of.

I am a little uncertain as to what exactly the question seeks.

If it is about whether to use "private" subroutines in your code, then there is really no accepted best practice. They are very useful, but they are not truly private. I use them, liberally.

A full answer is to use Moose or Moo, or some other module.

like image 44
zdim Avatar answered Jan 07 '23 08:01

zdim