Perl Moose 增强对比

标签 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>

...同样的结果。在设计“模型(对象层次结构)”时 - 基于我应该决定何时使用 aroundaugment ?

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

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

最佳答案

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 不能在角色中工作(检查父类(super class)的包的概念是在编译时绑定(bind)的,因此 $self->SUPER::method(@args) 将检查 角色 的父类(super class)(即无)而不是消耗角色 的 类的父类(super class)。如果你不使用角色,那么 SUPER 仍然可以在 Moose 类中使用就好了。TLDR:SUPER 被角色破坏,所以 Moose 给你 around 作为替代。

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

根据我的经验,augment 的实现有点脆弱,所以在我的书中是避免它的理由。不要尝试用 around 替换它,因为它们做的事情完全不同。相反,将其替换为我上面第一个示例中使用的模式。

关于Perl Moose 增强对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22557427/

相关文章:

perl - 如何监控属性的变化? (与更改/更改/属性相反)

perl - 为什么将 Perl OO 简单地用作数据封装技术?

perl - 从哈希引用中获取值

perl - DBM 文件可由生成该文件的计算机上的 Perl 脚本读取,但在其他计算机上为 "Inappropriate file type or format"

sql - 使用 perl 和 DBI 将一个非常大的表从一个 DB2 复制到另一个

perl - 谁能用 Perl 解释一下(我的 $self = shift)

具有多个相互依赖属性的 Perl Moose

perl - 使用 Moose::Meta::Class 或 Class::MOP::Class 生成正确的动态类

perl - “没有这样的文件或目录”,即使我拥有该文件并且它对每个人都有读取权限

perl - 使用 Event::Lib 制作 perl 聊天客户端