gpt4 book ai didi

perl - Perl Moose 类中的私有(private)变量

转载 作者:行者123 更新时间:2023-12-05 01:04:32 24 4
gpt4 key购买 nike

我开始使用 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();

在两个类(class) PAPB我有一个私有(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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com