Perl Moose扩充vs周围

时间:2014-03-21 11:22:49

标签: perl moose

尝试了解Moose:

use Modern::Perl;

package FOO {
    use Moose;
    sub rep { say "  <report></report>"; }
    sub doc {
        say "<document>";
        inner();
        say "</document>";
    }
}

package BAR {
    use Moose;
    extends 'FOO';

    around 'rep' => sub {
        my $orig = shift;
        my $self = shift;
        say "<document>";
        $self->$orig(@_);
        say "</document>";
    };

    augment 'doc' => sub {
        say "  <report></report>";
    };
}

package main {
    BAR->new->rep;
    say "===";
    BAR->new->doc;
}

...可生产

<document>
  <report></report>
</document>
===
<document>
  <report></report>
</document>

......同样的结果。当设计&#34;模型(对象层次结构)&#34; - 根据我应该决定何时使用around和何时使用augment

这可能是我目前还不了解的其他(更深层次的)事物

可以请某人提供更深入的&#34;解释,因为阅读tru Moose/Manual/MethodModifiers显然没有足够的帮助......

2 个答案:

答案 0 :(得分:5)

augmentaround做了不同的事情。 augment旨在简化此类模式:

package Document {
  use Moose;
  sub make_document {
    my $self = shift;
    return "<doc>" . $self->_document_innards . "</doc>"
  }
  # stub; override in child class
  sub _document_innards {
    my $self = shift;
    return "";
  }
}

package Invoice {
  use Moose;
  extends 'Document';
  sub _document_innards {
    my $self = shift;
    return "Give me money!";
  }
}

augment变为:

package Document {
  use Moose;
  sub make_document {
    my $self = shift;
    return "<doc>" . inner() . "</doc>"
  }
}

package Invoice {
  use Moose;
  extends 'Document';
  augment make_document => sub {
    my $self = shift;
    return "Give me money!";
  };
}

另一方面,around用于替换$self->SUPER::method(@args),因为SUPER无法在角色中工作(检查超类的包绑定的概念是什么编译时,$self->SUPER::method(@args)会检查角色的超类(即无),而不是消耗角色的类的超类。如果你不是使用角色,然后SUPER仍然可以在Moose类中使用.TLDR:SUPER被角色打破,所以Moose会给你around作为替代。

要比较的另一件事是override,它有点像around,但是为您提供了这个super()函数,它可能比$self->$orig(@_)稍微清晰一些。它还具有"there can be only one"功能。如果两个角色试图为同一个方法提供around修饰符,那很好:它们都可以包装方法(尽管它们的应用顺序是未定义的)。如果两个角色尝试提供override修饰符,那就是错误。

augment的实施在我的经历中有点脆弱,所以在我的书中是避免它的理由。不要试图用around替换它,因为它们确实做了不同的事情。而是用我上面第一个例子中使用的模式替换它。

答案 1 :(得分:1)

使用around应始终是您的第一直觉。作为(Moose创作者)Stevan Little says about augment

  

值得庆幸的是,只有一小部分人真正了解这一点   功能和那些人中只有少数人疯狂到   尝试使用它。