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

发布于 2024-09-28 11:28:09 字数 132 浏览 2 评论 0原文

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

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

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

I would like some attributes (perhaps this is the wrong term in this context) to be private, that is, only internal for the object use - can't be read or written from the outside.

For example, think of some internal variable that counts the number of times any of a set of methods was called.

Where and how should I define such a variable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

枯寂 2024-10-05 11:28:09

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

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

设置 init_arg 意味着该属性不能在构造函数中设置。如果您需要更新它,请将其设为 rw 或添加 writer

/I3az/

The Moose::Manual::Attributes shows the following way to create private attributes:

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

Setting init_arg means this attribute cannot be set at the constructor. Make it a rw or add writer if you need to update it.

/I3az/

雨后彩虹 2024-10-05 11:28:09

你可以尝试这样的事情:

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

is =>; 'ro' 使属性只读。 Moose 生成吸气剂。您的方法将使用 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。但按照惯例,应用程序不会调用以下划线开头的方法。

You can try something like this:

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

is => 'ro' makes the attribute read only. Moose generates a getter. Your methods will use the getter for incrementing the value, like so:

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

writer => '_set_call_counter' generates a setter named _set_call_counter. Moose does not support true private attributes. Outside code can, technically, call _set_call_counter. By convention, though, applications do not call methods beginning with an underscore.

黑寡妇 2024-10-05 11:28:09

我认为您想要 MooseX::Privacy

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

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

I think you want MooseX::Privacy.

The perldoc tells you all you should need - it adds a new trait to your attributes allowing you to declare them as private or protected:

has config => (
    is     => 'rw',
    isa    => 'Some::Config',
    traits => [qw/Private/],
);
七婞 2024-10-05 11:28:09

我一直无法找到一种方法使 Moose 属性完全私有。每当我使用 has 'name' =>; (...); 要创建一个属性,它总是至少暴露于读取。对于我想要真正私有的项目,我在 Moose 包中使用标准的“我的”变量。作为一个快速示例,请使用以下模块“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 的新手,但据我所知,这种方法提供了完全私有的变量。

I haven't been able to figure out a way to make Moose attributes completely private. Whenever I use has 'name' => (...); to create an attribute, it is always exposed to reading at a minimum. For items I want to be truly private, I'm using standard "my" variables inside the Moose package. For a quick example, take the following module "CountingObject.pm".

package CountingObject;

use Moose;

my $cntr = 0;

sub add_one { $cntr++; }

sub get_count { return $cntr; }

1;

Scripts that use that module have no direct access to the $cntr variable. They must use the "add_one" and "get_count" methods which act as an interface to the outside world. For example:

#!/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;

I'm new to Moose, but as far as I can tell, this approach provides completely private variables.

风铃鹿 2024-10-05 11:28:09

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

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

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

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;

Alan W. Smith provided a private class variable with a lexical variable, but it is shared by all objects in the class. Try adding a new object to the end of the example script:

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

Using MooseX:Privacy is a good answer, though if you can't, you can borrow a trick from the inside-out object camp:

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;

With that, each object's counter is stored as an entry in a lexical hash. The above can be implemented a little more tersely thus:

package CountingObject;

use Moose;

my %cntr;

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

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

1;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文