4

我的 Moose 课程使用了一个我不允许更改的角色。该角色定义了一个具有默认值的属性。我需要我的班级具有该属性,但具有不同的默认值。

那可能吗?

我所能想到的就是用我自己的一些代码围绕“新”方法,如下所示:

around new => sub {
    my ($orig, $self) = (shift, shift);
    return $self->$orig(@_, the_attribute => $new_value);
}

但我不确定围绕 new 是否有效,并且还希望有更优雅的东西。

4

2 回答 2

8

一个更好、更简单的方法是在你的类中写这个:

has '+the_attribute' => (
    default => sub{1},
}

has使用 a+可以只覆盖属性的特定属性。

比周围的 BUILDARGS 简单得多。

于 2013-03-10T22:53:15.267 回答
4

你有正确的想法,但你不应该覆盖new. Moose::Manual::BestPractices说:

永远不要覆盖新的

覆盖new是一种非常糟糕的做法。相反,您应该使用 a BUILDorBUILDARGS方法来做同样的事情。当你 overridenew时,当你的类不可变时,Moose 不能再内联构造函数。

我已经有一段时间没有这样做了,但我认为以下方法可以解决问题:

around BUILDARGS => sub {
   my $orig  = shift;
   my $class = shift;
   return $self->$orig(
      the_attribute => $new_value,
      @_ == 1 ? %{ $_[0] } : @_,
   );
};

笔记:

  • 我首先放置了新属性以允许它被覆盖。
  • 我做到了,->new({ ... })而且->new(...)仍然有效。如果你不关心 break ,你可以使用@_而不是。@_ == 1 ? %{ $_[0] } : @_->new({ ... })
于 2013-03-10T18:36:25.990 回答