为什么 Moose 的构建器采用字符串值?
作为使用子例程引用[默认]的替代方法,您可以为属性提供构建器方法: ... 这有几个优点。 首先,它将一段代码移动到自己的命名方法中,从而提高了可读性和代码组织。
因此,您的属性可以这样定义默认值:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当构建器被调用时,会发生这种情况:
如果构建器是一个字符串(比方说
build_attr
),那么用户可以在子类中编写自己的build_attr方法,并且它将被调用。 这使得默认值可以通过简单的命名方法机制进行扩展。如果它是对子例程的引用,则该引用是在原始类的包中获取的,这意味着它不能以相同的方式重写。
When the builder is called, this happens:
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.
这不是一个“象征性”参考。 构建器是一个方法名称。 这意味着它可以从角色继承和组合。 如果传递子例程引用,则该引用必须存在于同一包中(或者是完全限定的)。
我很确定我在手册中对此进行了解释。 还不清楚吗?
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?
子类化。
Builder 指定要调用的方法名称,因此
将为“子例程”的构建器调用 Something::subroutine ,而如果您使用 subref 样式,则将调用 YourClass::subroutine ,因为您直接引用了子例程而不是让它通过方法分派。
Subclassing.
Builder specifies a method name to call, so
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.