Perl Moose增强vs周围

caj*_*ine 3 perl 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;
}
Run Code Online (Sandbox Code Playgroud)

产生...

<document>
  <report></report>
</document>
===
<document>
  <report></report>
</document>
Run Code Online (Sandbox Code Playgroud)

...相同的结果。在设计“模型(对象层次结构)”时-基于我应该决定何时使用around以及何时使用的信息augment

这可能是我目前尚不了解的其他(更深入的)内容

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

tob*_*ink 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!";
  }
}
Run Code Online (Sandbox Code Playgroud)

有了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!";
  };
}
Run Code Online (Sandbox Code Playgroud)

另一方面,因为不能在角色中工作而around被用作执行操作的替代品(检查超类的包的概念在编译时是绑定的,所以将检查角色的超类(即,不检查)而不是超类)在的那所消耗的角色类。如果你不使用的角色,那么仍然可以在穆斯类中使用就好TLDR:由角色打破,所以穆斯给你作为替代。$self->SUPER::method(@args)SUPER$self->SUPER::method(@args)SUPERSUPERaround

要比较的另一件事override是有点像around,但是为您提供了此super()功能,该功能可能比$self->$orig(@_)。它还具有“只能有一个”功能。如果两个角色试图around为同一方法提供修饰符,那很好:它们都可以包装该方法(尽管应用它们的顺序是不确定的)。如果两个角色试图提供override修饰符,那就是错误的。

根据augment我的经验,实现的过程有些脆弱,因此在我的书中避免这样做是有原因的。不要尝试将其替换为around,因为它们做的事情截然不同。相反,将其替换为上面我的第一个示例中使用的模式。