取势 明道 优术

作者为 扶 凯 发表

 概要

  package BinaryTree;
  use Moose;

  has 'node' => (is => 'rw', isa => 'Any');

  has 'parent' => (
      is        => 'rw',
      isa       => 'BinaryTree',
      predicate => 'has_parent',
      weak_ref  => 1,
  );

  has 'left' => (
      is        => 'rw',
      isa       => 'BinaryTree',
      predicate => 'has_left',
      lazy      => 1,
      builder   => '_build_child_tree',
  );

  has 'right' => (
      is        => 'rw',
      isa       => 'BinaryTree',
      predicate => 'has_right',
      lazy      => 1,
      builder   => '_build_child_tree',
  );

  before 'right', 'left' => sub {
      my ($self, $tree) = @_;
      $tree->parent($self) if defined $tree;
  };

  sub _build_child_tree {
      my $self = shift;

      return BinaryTree->new( parent => $self );
  }

描述

如果你已经读过 Moose::Cookbook::Basics::Recipe3 ,这个例子,你就会非常的熟悉这个例子.实际上,我要在这个地方要全部替换掉所有的属性中 default 参数为 builder.
在这个例子中,这个 default 和 builder 选项的行为方式完全相同.当读 left 或者 right 属性的时候,Moose 调用 builder 方法来初始化属性.

注意什么时候 Moose 会在对象上的属性创建时,调用的 builder 方法,下面是一个例子:

my $tree = BinaryTree->new();
my $left = $tree->left();

当 $tree->left() 调用的时候, Moose 会调用 $tree->_build_child_tree() .按规定给结果放到 left 的属性上. 如果我们类的原始构造函数,这个 builder 不会被调用.
在这 default 和 builder 之间有一些不同,builder 是子类,能组成 role. 可以看看 Moose::Manual::Attributes 更多详细的.

 

lazy_build 的属性

您还可以使用属性选项 lazy_build 的语法糖.一次性指定全部的属性的选项.

has 'animal' => (
      is         => 'ro',
      isa        => 'Animal',
      lazy_build => 1,
  );

这是一个简写:

has 'animal' => (
      is        => 'ro',
      isa       => 'Animal',
      required  => 1,
      lazy      => 1,
      builder   => '_build_animal',
      predicate => 'has_animal',
      clearer   => 'clear_animal',
);

 

如果你的属性是以下划线开头,Moose 会非常聪明的,用 predicate 和 clearer 加载正确的函数,记得使他们都以下划线开始.函数构建方法总是以下划线开始.
你可以读读 Moose::Meta::Attribute 中有关 lazy_build 中的介绍.

结论

这个 builder 的选项是更加友好的 OO 中的默认功能,你可以使用一个明确的方法来默认生成的一些功能.因为匿名子程序的属性定义看起来可能很丑陋,很难跟进.

 

来了就留个评论吧! 没有评论