为什么Moose的构建器采用字符串值?

时间:2009-02-18 16:10:44

标签: perl moose

Moose::Manual::Attributes州:

  

作为使用子例程引用[默认]的替代方法,您可以为属性提供构建器方法:   ...   这有几个优点。首先,它将一大块代码移动到自己的命名方法,从而提高了可读性和代码组织。

因此,您的属性可以定义默认值:

has attr => (
  is => 'ro',
  builder => 'subroutine'
);
sub subroutine {
  # figure out and return default value
}

我不明白为什么它必须与默认分开。难道你不能只是传递对命名子程序的引用吗?

has attr => (
  is => 'ro',
  default => \&subroutine
);

那不是更好的编程习惯,因为你保证不会意外地引用一个不存在的子程序吗?您将使用逻辑引用而不是符号引用来引用该方法。

3 个答案:

答案 0 :(得分:14)

调用构建器时,会发生这种情况:

$object->$builder

如果builder是一个字符串(比如说build_attr),那么用户可以在子类中编写自己的build_attr方法,然后调用它。这使得默认值可以通过简单的命名方法机制进行扩展。

如果它是对子程序的引用,则引用将在原始类的包中进行,这意味着它不能以相同的方式覆盖。

答案 1 :(得分:10)

这不是“象征性”的参考。构建器是方法名称。这意味着它可以从角色继承和组合。如果传递子例程引用,则该引用必须存在于同一个包中(或完全限定)。

我很确定我在手册中解释了这一点。目前还不清楚吗?

答案 2 :(得分:7)

子类。

Builder指定要调用的方法名称,所以

package Something;
use Moose;

extends 'YourClass';

sub subroutine { <some other default> }

将Something :: subroutine调用为'subroutine'的构建器,而如果你使用了subref样式,那么将调用YourClass :: subroutine,因为你直接引用了子程序而不是让它通过方法调度。