为什么 Moose 的构建器采用字符串值?

发布于 2024-07-13 15:52:41 字数 665 浏览 6 评论 0原文

Moose::Manual::Attributes 状态:

作为使用子例程引用[默认]的替代方法,您可以为属性提供构建器方法: ... 这有几个优点。 首先,它将一段代码移动到自己的命名方法中,从而提高了可读性和代码组织。

因此,您的属性可以这样定义默认值:

has attr => (
  is => 'ro',
  builder => 'subroutine'
);
sub subroutine {
  # figure out and return default value
}

我不明白为什么它必须与默认值分开。 您不能只传递对命名子例程的引用吗?

has attr => (
  is => 'ro',
  default => \&subroutine
);

这不是更好的编程实践吗?因为你保证不会意外地引用不存在的子例程? 您将使用逻辑引用而不是符号引用来引用该方法。

Moose::Manual::Attributes states:

As an alternative to using a subroutine reference [for default], you can instead supply a builder method for your attribute:
...
This has several advantages. First, it moves a chunk of code to its own named method, which improves readability and code organization.

So, your attribute could define a default thusly:

has attr => (
  is => 'ro',
  builder => 'subroutine'
);
sub subroutine {
  # figure out and return default value
}

I don't get why this has to be separate from default. Couldn't you just pass a reference to a named subroutine?

has attr => (
  is => 'ro',
  default => \&subroutine
);

And would that not be better programming practice, since you're guaranteed not to accidentally refer to a subroutine that doesn't exist? You'd be referring to the method with a logical reference instead of a symbolic reference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

闻呓 2024-07-20 15:52:41

当构建器被调用时,会发生这种情况:

$object->$builder

如果构建器是一个字符串(比方说build_attr),那么用户可以在子类中编写自己的build_attr方法,并且它将被调用。 这使得默认值可以通过简单的命名方法机制进行扩展。

如果它是对子例程的引用,则该引用是在原始类的包中获取的,这意味着它不能以相同的方式重写。

When the builder is called, this happens:

$object->$builder

If builder is a string (let's say build_attr), then users can write their own build_attr method in a subclass and it will be called. This makes the default value extensible via a simple named method mechanism.

If it's a reference to a subroutine, the reference is taken in the original class's package, which means it can't be overriden the same way.

我偏爱纯白色 2024-07-20 15:52:41

这不是一个“象征性”参考。 构建器是一个方法名称。 这意味着它可以从角色继承和组合。 如果传递子例程引用,则该引用必须存在于同一包中(或者是完全限定的)。

我很确定我在手册中对此进行了解释。 还不清楚吗?

It's not a "symbolic" reference. The builder is a method name. That means it is inheritable and composable from a role. If you pass a subroutine reference, that reference must exist in the same package (or be fully qualified).

I'm pretty sure I explain this in the manual. Is it unclear?

决绝 2024-07-20 15:52:41

子类化。

Builder 指定要调用的方法名称,因此

package Something;
use Moose;

extends 'YourClass';

sub subroutine { <some other default> }

将为“子例程”的构建器调用 Something::subroutine ,而如果您使用 subref 样式,则将调用 YourClass::subroutine ,因为您直接引用了子例程而不是让它通过方法分派。

Subclassing.

Builder specifies a method name to call, so

package Something;
use Moose;

extends 'YourClass';

sub subroutine { <some other default> }

would have Something::subroutine called for a builder of 'subroutine', whereas if you used the subref style then the YourClass::subroutine would be called instead because you've made a direct reference to the subroutine rather than letting it go through method dispatch.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文