首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么在Moose中声明一个返回子例程引用的子例程?

为什么在Moose中声明一个返回子例程引用的子例程?
EN

Stack Overflow用户
提问于 2013-07-16 02:49:02
回答 1查看 96关注 0票数 0

我对perl中的Moose很陌生,当我遇到这个文档时,我一直在阅读它的文档,而我并不完全理解这个文档:

如果要使用任何类型的引用作为默认值,则必须从子例程返回该引用。好的,我得到这条语句,下一个例子是

代码语言:javascript
运行
复制
has 'mapping' => (
      is      => 'ro',
      default => sub { {} },
  );

这是必要的,因为否则Perl将实例化引用一次,并且它将被所有对象共享:--我不理解的--这意味着它将实例化引用一次,并由所有对象共享。怎么做?

代码语言:javascript
运行
复制
 has 'mapping' => (
      is      => 'ro',
      default => {}, # wrong!
  );

如果将一个空的非子例程引用作为默认值传递,驼鹿将抛出一个错误。

如果Moose允许这样做,那么默认的映射属性很容易在许多对象之间共享。相反,将它包装在一个子程序引用中,就像我们前面看到的那样。,不要再这样了,

EN

回答 1

Stack Overflow用户

发布于 2013-07-16 08:26:13

因为它会在一定距离内产生动作,这是不好的。说明这一问题:

代码语言:javascript
运行
复制
package Wrong;
my $default = {};

sub new {
    my ($class) = @_;
    return bless $default => $class;
}

package main;
use 5.010;
my @wobj;
push @wobj, Wrong->new for 0..2;

$wobj[0]->{some_new_attr} = 'foobar';

use Data::Dumper qw(Dumper);
print Dumper $wobj[1];  # huh????!
print Dumper $wobj[2];  # that one, too?! why?

say for @wobj;          # ah, it's the same shared address

package Correct;
my $default = sub { return {} };

sub new {
    my ($class) = @_;
    return bless $default->() => $class;
}

package main;
my @cobj;
push @cobj, Correct->new for 0..2;

$cobj[0]->{some_new_attr} = 'foobar';

print Dumper $cobj[$_] for 0..2; # instances 1 and 2 are unaffected

say for @cobj;          # all different addresses
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17667193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档