perl – Moose深度强制 – 用户定义类型的ArrayRef
发布时间:2020-12-15 21:45:09 所属栏目:大数据 来源:网络整理
导读:我在以下子类型和强制链中缺少什么?我希望能够强制验证类型的arrayref或死于以下输入: 强制字符串 有效字符串 具有混合强制和有效字符串的Arrayref 假设所有类型都是完全命名空间,并且未声明的函数validate和coerce_str validate(返回bool)并强制并分别从
我在以下子类型和强制链中缺少什么?我希望能够强制验证类型的arrayref或死于以下输入:
>强制字符串 假设所有类型都是完全命名空间,并且未声明的函数validate和coerce_str validate(返回bool)并强制并分别从输入中返回有效字符串. subtype 'CustomType' => as 'Str' => where { validate($_) } ; coerce 'CustomType' => from 'Str' => via { if (my $coerced = coerce_str($_)) { return $coerced; } return $_; } ; subtype 'ArrayRefofCustomTypes' => as 'ArrayRef[CustomType]' ; coerce 'ArrayRefofCustomTypes' => from 'CustomType' => via { [ $_ ] } ; has 'values' => ( is => 'ro',required => 1,isa => 'ArrayRefofCustomTypes',coerce => 1,); 我知道CustomType有效;因为我可以定义一个属性,并使用强制字符串或已经有效的字符串初始化对象.我不确定该怎么做的是显式地处理从构造函数中传递到传递的arrayref并单独验证所有包含的字符串.我已经阅读了关于深度强制(http://search.cpan.org/dist/Moose/lib/Moose/Manual/Types.pod#Deep_coercion)的文档几次,我只是不太明白,我希望有人可以指出我正确的方向.谢谢! 在这里,我将其简化为更简洁的概述,但是: { package My::Class; use strict; use warnings; use Moose; use Moose::Util::TypeConstraints; subtype 'CustomType' => as 'Str' => where { validate($_) } ; coerce 'CustomType' => from 'Str' => via { if (my $coerced = coerce_str($_)) { return $coerced; } return $_; } ; subtype 'ArrayRefofCustomTypes' => as 'ArrayRef[CustomType]' ; coerce 'ArrayRefofCustomTypes' => from 'CustomType' => via { [ $_ ] } ; has 'values' => ( is => 'ro',); sub validate { my $val = shift; if ($val =~ /^w+$/) { return 1; } return (); } sub coerce_str { my $val = shift; $val =~ s/W/_/g; return $val; } } { package main; use strict; use warnings; use Test::More qw/no_plan/; new_ok( 'My::Class' => [ values => [ 'valid' ] ]); #ok new_ok( 'My::Class' => [ values => [ qw/valid valid still_valid/ ] ]); #ok new_ok( 'My::Class' => [ values => 'valid' ]); # ok new_ok( 'My::Class' => [ values => [ 'invalid; needs some coercion - ^&%&^' ] ]); #not ok new_ok( 'My::Class' => [ values => 'invalid; needs some coercion - ^&%&^' ]); # not ok cmp_ok( My::Class::coerce_str('invalid; needs some coercion - ^&%&^'),'eq','invalid__needs_some_coercion________','properly coerces strings'); #ok } 按原样运行给出了以下内容.问题不是验证,而是我没有明确定义我的强制,我不确定我缺少什么: ok 1 - The object isa My::Class ok 2 - The object isa My::Class ok 3 - The object isa My::Class not ok 4 - new() died # Failed test 'new() died' # at testcoercion.pl line 63. # Error was: Attribute (values) does not pass the type constraint because: Validation failed for 'ArrayRefofCustomTypes' with value [ "invalid; needs some coercion - ^&%&^" ] at C:/strawberry/perl/site/lib/Moose/Meta/Attribute.pm line 1131 << cut >> not ok 5 - new() died # Failed test 'new() died' # at testcoercion.pl line 64. # Error was: Attribute (values) does not pass the type constraint because: Validation failed for 'ArrayRefofCustomTypes' with value "invalid; needs some coercion - ^&%&^" at C:/strawberry/perl/site/lib/Moose/Meta/Attribute.pm line 1131 << cut >> ok 6 - properly coerces strings 1..6 # Looks like you failed 2 tests of 6. 解决方法
你使用的一切都应该工作正常.例如,考虑这个测试:
my $customtype = Moose::Util::TypeConstraints::find_type_constraint('CustomType'); print "'a' validates as customtype? ",($customtype->check('a') ? 'yes' : 'no'),"n"; my $arraytype = Moose::Util::TypeConstraints::find_type_constraint('ArrayRefofCustomTypes'); print "[ 'a' ] validates as array? ",($arraytype->check([ 'a' ]) ? 'yes' : 'no'),"n"; { package Class; use Moose; has 'values' => ( is => 'ro',); } my $obj = Class->new(values => 'a'); print $obj->dump(2); 这打印: 'a' validates as customtype? yes [ 'a' ] validates as array? yes $VAR1 = bless( { 'values' => [ 'a' ] },'Class' ); 结论:如果遇到问题,可以使用其他代码.你能粘贴一些不能按预期工作的代码吗? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |