Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl Moose:重写派生类中属性的`required`ness_Perl_Moose - Fatal编程技术网

Perl Moose:重写派生类中属性的`required`ness

Perl Moose:重写派生类中属性的`required`ness,perl,moose,Perl,Moose,我有一个基类和十几个派生类。除一个派生类外,所有派生类都需要名为key的属性。因此,我可以将它添加到11个派生类中,而不使用第12个派生类 但是,懒惰就是它,我想把属性添加到基类中,从而避免重复声明十一次,并且添加我认为的一致性和简单性。 现在,对于一个不需要键属性的类来说,这带来了一个问题。请注意,如果该类具有此属性,但它不需要此属性,则不会有任何危害 我的想法是通过使用标记方法is_strict来解决这个问题,该方法将从BUILDARGS调用,以确定是否需要键。下面是一个简单的脚本来说明这一

我有一个基类和十几个派生类。除一个派生类外,所有派生类都需要名为
key
的属性。因此,我可以将它添加到11个派生类中,而不使用第12个派生类

<>但是,懒惰就是它,我想把属性添加到基类中,从而避免重复声明十一次,并且添加我认为的一致性和简单性。

现在,对于一个不需要
属性的类来说,这带来了一个问题。请注意,如果该类具有此属性,但它不需要此属性,则不会有任何危害

我的想法是通过使用标记方法
is_strict
来解决这个问题,该方法将从
BUILDARGS
调用,以确定是否需要
键。下面是一个简单的脚本来说明这一点(好吧,我颠倒了概念,
属性只在一种情况下需要(而不是在除一种情况外的所有情况下),但问题仍然受到这种反转的影响):


这是可行的,但是有没有更好的方法来实现我想要的呢?

好吧,我有点傻,因为我没有尝试最明显的解决方案,只是覆盖派生类中的属性定义,其中所需属性与默认属性不同。我们开始:

#!perl
package Bla;
use Moose;
use Carp ();
has grop => is => 'ro', isa => 'Str'; # optional
has key  => is => 'ro', isa => 'Int'; # required in all but one cases
# imagine a bunch of other stuff here shared by all derived classes
no Moose; __PACKAGE__->meta->make_immutable;

package Bla::Eins;
use Moose; extends 'Bla';
no Moose; __PACKAGE__->meta->make_immutable;

package Bla::Zwei;
use Moose; extends 'Bla';
no Moose; __PACKAGE__->meta->make_immutable;

package Bla::Drei;
use Moose; extends 'Bla';
# prefix an attribute you're overriding with a "+" sign
has '+key' => is => 'ro', isa => 'Int', required => 1;
no Moose; __PACKAGE__->meta->make_immutable;

package main;
use Test::More;
use Test::Exception;
lives_ok  { Bla::Eins->new };
lives_ok  { Bla::Zwei->new };
throws_ok { Bla::Drei->new } qr/\bkey\b.*\brequired\b/;
lives_ok  { Bla::Drei->new( key => 99 ) };
done_testing;
尽管如此,我还是感谢所有的反馈,因为这个Mooseland没有其他语言中的对象系统好


啊,我看到你应该在一个属性定义前面加上前缀,你要用
+
覆盖它,所以如果在父类中找不到被引用的属性,Moose会可怜地发出
咯咯声,为你的代码增加安全性和一致性。我已经相应地更新了示例代码。

您可以将
requires=>1
放在原始代码中,并使用
has'+key'=>(requires=>0)
将其关闭,而不是使用
has'+key'=>。在最初的请求中,有11个是必需的,只有一个不是必需的,因此这意味着只有一个定义需要覆盖,而其他11个定义可以保持不变。

“+键”还将复制属性中的其他特征,因此您只需要指定增量,即:
has“+键”=>(必需=>1)
#!perl
package Bla;
use Moose;
use Carp ();
has grop => is => 'ro', isa => 'Str'; # optional
has key  => is => 'ro', isa => 'Int'; # required in all but one cases
# imagine a bunch of other stuff here shared by all derived classes
no Moose; __PACKAGE__->meta->make_immutable;

package Bla::Eins;
use Moose; extends 'Bla';
no Moose; __PACKAGE__->meta->make_immutable;

package Bla::Zwei;
use Moose; extends 'Bla';
no Moose; __PACKAGE__->meta->make_immutable;

package Bla::Drei;
use Moose; extends 'Bla';
# prefix an attribute you're overriding with a "+" sign
has '+key' => is => 'ro', isa => 'Int', required => 1;
no Moose; __PACKAGE__->meta->make_immutable;

package main;
use Test::More;
use Test::Exception;
lives_ok  { Bla::Eins->new };
lives_ok  { Bla::Zwei->new };
throws_ok { Bla::Drei->new } qr/\bkey\b.*\brequired\b/;
lives_ok  { Bla::Drei->new( key => 99 ) };
done_testing;