如何创建内部(私有)Moose对象变量(属性)?

时间:2010-10-22 11:52:18

标签: perl moose

我想要一些属性(也许这是在这种情况下这是错误的术语)是私有的,也就是说,只有内部用于对象使用 - 不能从外部读取或写入。

例如,考虑一些内部变量,它计算调用任何一组方法的次数。

我应该在哪里以及如何定义这样的变量?

5 个答案:

答案 0 :(得分:15)

Moose::Manual::Attributes显示以下创建私有属性的方法:

has '_genetic_code' => (
   is       => 'ro',
   lazy     => 1,
   builder  => '_build_genetic_code',
   init_arg => undef,
);

设置init_arg表示无法在构造函数中设置此属性。如果您需要更新,请将其设为rw或添加writer

/ I3az /

答案 1 :(得分:10)

您可以尝试这样的事情:

has 'call_counter' => (
    is     => 'ro',
    writer => '_set_call_counter',
);

is => 'ro'使属性只读。穆斯产生一个吸气剂。您的方法将使用getter来增加值,如下所示:

sub called {
    my $self = shift;
    $self->_set_call_counter( $self->call_counter + 1 );
    ...
}

writer => '_set_call_counter'会生成一个名为_set_call_counter的setter。 Moose不支持真正的私有属性。从技术上讲,外部代码可以调用_set_call_counter。但是,按照惯例,应用程序不会调用以下划线开头的方法。

答案 2 :(得分:7)

我想你想要MooseX::Privacy

perldoc会告诉您所需的一切 - 它会为您的属性添加一个新特征,允许您将它们声明为私有或受保护:

has config => (
    is     => 'rw',
    isa    => 'Some::Config',
    traits => [qw/Private/],
);

答案 3 :(得分:3)

Alan W. Smith提供了一个带有词法变量的私有类变量,但它由类中的所有对象共享。尝试在示例脚本的末尾添加一个新对象:

my $c1 = CountingObject->new();
printf( "%s\n", $c1->get_count() );
#  also shows a count of 10, same as $co

使用MooseX:隐私是一个很好的答案,但如果你不能,你可以从内到外的对象阵营中借用一个技巧:

package CountingObject;

use Moose;

my %cntr;

sub BUILD { my $self = shift; $cntr{$self} = 0 }

sub add_one { my $self = shift; $cntr{$self}++; }

sub get_count { my $self = shift; return $cntr{$self}; }

1;

这样,每个对象的计数器都存储为词法哈希中的条目。因此可以更加简洁地实现上述目标:

package CountingObject;

use Moose;

my %cntr;

sub add_one { $cntr{$_[0]}++ }

sub get_count { return $cntr{$_[0]}||0 }

1;

答案 4 :(得分:2)

我无法找到一种让Moose属性完全隐私的方法。每当我使用has 'name' => (...);创建一个属性时,它总是会被阅读至少。对于我想要真正私密的项目,我在Moose包中使用标准的“my”变量。有关快速示例,请使用以下模块“CountingObject.pm”。

package CountingObject;

use Moose;

my $cntr = 0;

sub add_one { $cntr++; }

sub get_count { return $cntr; }

1;

使用该模块的脚本无法直接访问$ cntr变量。他们必须使用“add_one”和“get_count”方法,这些方法充当外部世界的接口。例如:

#!/usr/bin/perl 

### Call and create
use CountingObject;
my $co = CountingObject->new();

### This works: prints 0
printf( "%s\n", $co->get_count() );

### This works to update $cntr through the method
for (1..10) { $co->add_one(); }

### This works: prints 10
printf( "%s\n", $co->get_count() );

### Direct access won't work. These would fail:
# say $cntr;
# say $co->cntr;

我是Moose的新手,但据我所知,这种方法提供了完全私有的变量。