如果您正在寻找类似Java的方法隐私性,那么MooseX::Privacy会让您大失所望。以下是Java风格方法隐私性的情况:
public class Main
{
public class MyParent
{
private String message_string ()
{
return "Message from %s\n";
}
public void print_message ()
{
System.out.printf( this.message_string(), "MyParent" );
}
}
public class MyChild extends MyParent
{
public String message_string ()
{
return "Another message from %s\n";
}
}
public static void main (String[] args)
{
Main o = new Main();
o.run();
}
public void run ()
{
MyParent c = new MyChild();
c.print_message();
}
}
你可以像这样编译和运行此示例:
$ javac Main.java
$ java Main
Message from MyParent
请注意发生了什么。父类(
MyParent
)声明
message_string()
为私有方法。子类试图覆盖该方法,但被坚决拒绝 - 子类,你不能这样做!
现在让我们尝试使用Perl和MooseX::Privacy进行等效操作...
use v5.14;
use strict;
use warnings;
package MyParent {
use Moose;
use MooseX::Privacy;
private_method message_string => sub {
my $self = shift;
return "Message from %s\n";
};
sub print_message {
my $self = shift;
printf($self->message_string(), __PACKAGE__);
}
}
package MyChild {
use Moose; extends qw(MyParent);
use MooseX::Privacy;
sub message_string {
my $self = shift;
return "Another message from %s\n";
}
}
my $c = new MyChild();
$c->print_message();
我们可以这样运行:
$ perl Main.pl
Another message from MyParent
说实话,message_string
不是应该是私有的吗?!MyChild
怎么可能重写MyParent
中的方法?!
事实是,MooseX::Privacy并不能像大多数面向对象语言中实现的方法私有化一样为你提供任何接近的东西。MooseX::Privacy只是类似于在你的方法中这样做:
die "GO AWAY!!" unless caller eq __PACKAGE__;
除非你想在所有方法调用时增加巨大的运行时开销,否则不要使用MooseX::Privacy。
事实上,使用MooseX::Privacy的理由很少。如果你想要私有方法,可以将它们放在词法变量中。就像这样:
use v5.14;
use strict;
use warnings;
package MyParent {
use Moose;
my $message_string = sub {
my $self = shift;
return "Message from %s\n";
};
sub print_message {
my $self = shift;
printf($self->$message_string(), __PACKAGE__);
}
}
package MyChild {
use Moose; extends qw(MyParent);
sub message_string {
my $self = shift;
return "Another message from %s\n";
}
}
my $c = new MyChild();
$c->print_message();
现在运行它:
$ perl Main2.pl
Message from MyParent
哈利路亚!! 我们有了一个真正的私有方法!
好的,所以你可以没有MooseX::Privacy而拥有私有方法,它们比MooseX::Privacy更好(更快)。
但是私有属性怎么办?嗯,我在CPAN上有一个小模块可以帮助你:Lexical::Accessor。这是一个小工具,为您创建一个属性,使用“内部存储”(即属性值不会存储在对象的blessed哈希引用中),并在词法变量中安装其访问器(就像上面的私有$get_message
方法一样)。
无论如何,这是我对MooseX::Privacy的看法。
$var
是静态的,而PB的不是。除此之外,PA是否在第一时间使用Moose呢?如果您不了解Moose的优势,那么整个问题都是无意义的。 - rutterPA
中包含公共变量,以使示例最小化。 - Håkon Hægland