【问题标题】:Perl Moose augment vs aroundPerl Moose 增强与周围
【发布时间】:2014-03-21 11:22:48
【问题描述】:

尝试了解 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>

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

这里可能还有其他(更深层次的)事情我目前还不了解。

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

【问题讨论】:

    标签: perl moose


    【解决方案1】:

    augment 和 around 做的事情完全不同。 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-&gt;SUPER::method(@args) 的替代品,因为SUPER 不能在角色中工作(检查超类的包的概念是在编译时绑定的,所以@ 987654331@ 将检查 role 的超类(即无)而不是 使用该角色的类的超类。如果您不使用角色,那么 SUPER 可以仍然可以在 Moose 类中使用。TLDR:SUPER 被角色破坏,所以 Moose 给你around 作为替代。

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

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

    【讨论】:

    • 不应该是augment make_document吗?
    • 谢谢——这让事情变得更清楚了:) 主要是因为学习Mason/Moose 和梅森的力量主要基于augmented 方法。 (页面的嵌套渲染)。
    【解决方案2】:

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

    谢天谢地,只有一小部分人真正理解这一点 功能,而在这些人中,只有少数人足够疯狂 尝试使用它。

    【讨论】:

    • 不过,这并不能真正解释差异。
    • Mason2 的作者非常疯狂地使用它非常成功;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多