我开始使用 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();
在
PA
和 PB
类中,我都有一个私有(private)变量 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();
}
}
你可以像这样编译和运行这个例子:
$ javac Main.java
$ java Main
Message from MyParent
注意发生了什么。父类 (
MyParent
) 将 message_string()
声明为私有(private)方法。子类尝试覆盖该方法,但遭到了全面拒绝 - 没有适合您的汤 子类!现在让我们试试 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();
我们可以这样运行:
$ perl Main.pl
Another message from MyParent
说, WHA?!?!?!
message_string
不应该是私有(private)的吗?! MyChild
到底是怎么覆盖 MyParent
中的方法的?!事实是,MooseX::Privacy 并没有为您提供任何接近大多数 OO 语言中实现的方法隐私的东西。 MooseX::Privacy 类似于在您的方法中执行此操作:
die "GO AWAY!!" unless caller eq __PACKAGE__;
除了 MooseX::Privacy 为您的所有方法调用增加了大量的运行时间。
真的,几乎没有理由使用 MooseX::Privacy。如果您想要私有(private)方法,请将它们放在词法变量中。像这样:
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
哈利路亚!! 我们有一个真正的私有(private)方法!
好的,所以您可以拥有没有 MooseX::Privacy 的私有(private)方法,并且它们比 MooseX::Privacy 更好(更快)。
但是私有(private)属性呢?好吧,我有一个关于 CPAN 的小模块可以帮助你: Lexical::Accessor 。这是一个为您创建属性的小工具,具有“由内而外”存储(即属性值不会存储在对象的祝福 hashref 中),并将其访问器安装在词法变量中(就像私有(private)
$get_message
方法同上)。无论如何,这就是我对 MooseX::Privacy 的看法。
关于perl - Perl Moose 类中的私有(private)变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22972602/