所以我想给我的其他子程序带一些鼠标速度并做一些类型检查
sub mysub {
my ($self, $int) = @_;
assert_int($int, 'int[1]');
}
子程序参数是要断言的数据&此数据的可选名称。这样我们就会得到一个更有用的错误信息,例如
Assertion error! 'int[1]' is not an integer; got 'HASH(0xXXXXXXXXX)'
用纯Perl编写它并不难。将它与Mouse&中的速度进行比较时gfx的另一个模块Data :: Util,比纯Perl快4倍,很明显纯XS解决方案具有优势,但缺少这个可选参数名称。在Data :: Util的检查函数周围编写一个小包装器仍然比直接使用XS慢。
是否有人知道一套快速数据类型断言实用程序,它允许将此字段名称传递给断言?
在@ikegami回答关于如何使用鼠标类型系统之后编辑,与仅使用XS库相比,似乎仍然缺乏性能。所以问题变成了是否有一个基于XS的框架可以提供可自定义的错误消息,或者至少可以让你说出属性被称为。
编辑这是我目前正在比较性能的代码。这主要基于gfx在Data::Util
和Mouse
的XS模式下的工作。这使我们在纯Perl解决方案上的速度提高了5倍。将C与Perl进行比较有点不公平,这就是为什么我想知道一个框架是否已经存在,它可以提供这种性能但是有正确的错误信息。如果其他人已经做过,我不想写这些东西:)
use Inline C => <<'END_C';
static int S_nv_is_integer(pTHX_ NV const nv) {
if(nv == (NV)(IV)nv){
return TRUE;
}
else {
char buf[64]; /* Must fit sprintf/Gconvert of longest NV */
const char* p;
(void)Gconvert(nv, NV_DIG, 0, buf);
p = &buf[0];
/* -?[0-9]+ */
if(*p == '-') p++;
while(*p){
if(!isDIGIT(*p)){
return FALSE;
}
p++;
}
return TRUE;
}
}
int assert_int(SV* sv, char* attributeName) {
assert(sv);
int result;
if(SvPOKp(sv)){
int const num_type = grok_number(SvPVX(sv), SvCUR(sv), NULL);
result = num_type && !(num_type & IS_NUMBER_NOT_INT);
}
else if(SvIOKp(sv)){
result = TRUE;
}
else if(SvNOKp(sv)) {
result = S_nv_is_integer(aTHX_ SvNVX(sv));
}
else {
result = FALSE;
}
if(! result) {
croak("'%s' was not an integer; got '%s'", attributeName, SvPV(sv, PL_na));
}
return result;
}
END_C
答案 0 :(得分:3)
如果你想要什么鼠标使用,没有什么能阻止你。
my $int_constraint = Mouse::Util::TypeConstraints::find_type_constraint('Int');
sub mysub {
my ($self, $int) = @_;
$int_constraint->assert_valid($int);
...
}
如果您想提供自己的消息,请使用check or die
代替assert_valid
。
我在Moose中使用过它,但看起来它也适用于鼠标。