我开始使用Moose了解Perl中的对象.
我不确定我是否理解其目的MooseX::Privacy.考虑:
use v5.14;
package PA {
use Moose;
my $var='private?';
1;
sub getVar {
return $var;
}
}
package PB {
use Moose;
use MooseX::Privacy;
has 'var' => (
is => 'rw',
isa => 'Str',
default => 'private?',
traits => [qw/Private/],
);
1;
sub getVar {
my $self = shift;
return $self->var;
}
}
my $o1= PA->new();
my $o2= PB->new();
say $o1->getVar();
say $o2->getVar();
Run Code Online (Sandbox Code Playgroud)
在这两个阶级PA和PB我有一个私有变量var.只在PB我上课时使用MooseX::Privacy.这两种方法有什么区别?我为什么要用MooseX::Privacy?
如果您正在寻找Java风格的方法隐私,那么MooseX :: Privacy将会非常令人失望.以下是Java样式方法隐私的情况:
/* This file is called Main.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();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以像这样编译并运行此示例:
$ javac Main.java
$ java Main
Message from MyParent
Run Code Online (Sandbox Code Playgroud)
注意发生了什么.父类(MyParent)声明message_string()为私有方法.子类尝试覆盖该方法,但是被彻底拒绝 - 对于您的子类没有汤!
现在让我们尝试使用Perl和MooseX :: Privacy ...
# This file is called Main.pl
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();
Run Code Online (Sandbox Code Playgroud)
我们可以像这样运行:
$ perl Main.pl
Another message from MyParent
Run Code Online (Sandbox Code Playgroud)
说,WHA?!?!?!不message_string应该是私人的吗?!地狱怎么MyChild覆盖了这个方法MyParent?!
事实上,MooseX :: Privacy并没有像大多数OO语言那样为您提供方法隐私.MooseX ::隐私就像在你的方法中这样做:
die "GO AWAY!!" unless caller eq __PACKAGE__;
Run Code Online (Sandbox Code Playgroud)
除了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();
Run Code Online (Sandbox Code Playgroud)
现在运行它:
$ perl Main2.pl
Message from MyParent
Run Code Online (Sandbox Code Playgroud)
哈利路亚!我们有一个真正的私人方法!
好的,所以你可以拥有没有MooseX :: Privacy的私有方法,它们比MooseX :: Privacy更好(也更快).
但私有属性呢?好吧,我在CPAN上有一个小模块可以帮助你:Lexical :: Accessor.这是一个为您创建属性的小工具,具有"由内而外"存储(即属性值不会存储在对象的祝福hashref中),并在词法变量中安装它的访问器(就像私有$get_message方法一样)以上).
无论如何,这是我对MooseX :: Privacy的看法.