enn*_*ler 8 oop perl private-methods
我正在使用Damian Conway的"由内而外"的对象,如他所描述的那本精彩的书Perl Best Practices,用于在我的客户端构建面向对象的安全系统接口.我想在我的模块中使用内部帮助器方法,我通常将其指定为"_some_method".但是,这似乎打破了封装,因为它们可以通过包名直接调用.有没有办法让这些方法真正私密?举个例子,
use SOD::MyOOInterface;
my $instance1 = SOD::MyOOInterface->new();
$instance1->_some_method; #this produces an error:
SOD::MyOOInterface::_some_method; # this results in a
# successful method call
Run Code Online (Sandbox Code Playgroud)
显然我不希望_some_method的直接调用成功.有什么方法可以保证吗?
Ran*_*rtz 11
package Foo;
## declare inside-out hashes here:
my %attr_a;
my %attr_b;
## declare private methods here
my $private_1 = sub {
my $self = shift;
# can use $attr_a{$self} here...
...
};
my $private_2 = sub {
my $self = shift;
...
};
## public methods here
sub new { ... }
sub public_1 {
my $self = shift;
# can access attributes here
# can call private methods too, with slightly odd syntax:
my $result = $self->$private_1(@args);
...
}
1;
Run Code Online (Sandbox Code Playgroud)
有点.您无法隐藏已安装到符号表中的子例程,但您可以使用词法变量来保存对匿名子例程的引用:
package SOD::MyOOInterface;
my $some_method = sub { ... }
$some_method->();
Run Code Online (Sandbox Code Playgroud)
因为$some_method只在实现类的文件中可见,所以子程序不能在外部调用.缺点是它不能作为方法调用,必须作为函数调用.如果要将其用作方法,则必须显式传递对象引用:
$some_method->($obj, @args);
Run Code Online (Sandbox Code Playgroud)
不要将PBP用于对象实践.这是非常古老的.事实上,现在关于Perl和对象的最佳实践可以在Moose中找到,这对于Perl来说几乎是必须的.
简而言之,Perl模糊命名空间和类的方式可以在类上静态调用大多数方法.这不是坏事,只是不记录它.没有理由想要将方法密封到实例中.没有私人方法有点令人讨厌,但不依赖于无证方法的惯例是如此强烈,它已经足够我们的社区.
特征实际上是一个可以在运行时编译成对象的角色(不允许实例化).这将进一步模糊典型用户的方法来源(因为它们不会在原始类中),但它会以运行时成本出现.有关特征的更多信息,请参阅MooseX :: Traits.
前置下划线是一个很好的惯例,进一步说明该方法是专用于窥视眼睛.
就好像你真的想推动此问题的最后一个音符,你也许可以创建使用类:: MOP ::讲座> create_anon_class这些方法匿名类()