Perl doesn't support a friend relationship between objects, nor does it support private or protected methods. What is usually done for private methods is to prefix the name with an underscore. I occasionally have methods that I think of as friend methods. Meaning that I expect them to be used by a specific object, or an object with a specific responsibility, but I'm not sure if I should make that method public (meaning foo
) or private ( _foo
) or if there's a better convention? is there a convention for friend methods?
3 Answers
I'm not aware of any conventions or best practices for friend methods that the Perl community uses. If you felt the need to designate a prefix for these methods I don't see any real issue with it, but I don't see any advantage in it either. Personally I'd just make it a "public" method, without the underscore, and without any additional prefix.
Perl does not, by itself, enforce private methods or attributes, no. In fact, Larry Wall was once quoted as saying:
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.
If you're using Moose
(and if you aren't, you really, really should), you could put your method, which I'll call foo
, into a role, say Fooable
, that can be composed into more than one class, thus allowing foo
to be a method in any class that does
the Fooable
role.
If you want true privacy, though, it looks as though MooseX::Privacy
provides that, although I don't have any experience using it.
-
1only problem I have with the role's suggestion is that a role becomes a part of the object, and that would ultimately seriously violate the single responsibility principle in any case where I'm thinking about friend methods. Commented Sep 29, 2012 at 20:15
If you really want to have Friend semantics you could do something like this:
package A;
use Data::Dumper;
sub _friend
{
die "you are no friend of mine" unless caller(0)->isa(__PACKAGE__);
my $self = shift;
"friend";
}
package B;
use base 'A';
sub new
{
bless {}, shift;
}
sub test_friend
{
shift->_friend;
}
package main;
$bob = new B;
print $bob->test_friend, "\n";
print $bob->_friend, "\n";
I named the method with an underscore so that Test::Pod will will not complain that it is not documented.