2011-07-15 13 views
0

有一个现有的CPAN库,是能够从降低所传递的数据结构到真/假值基本测试,结构化输入创建coderefs创建减少?它需要能够从构造传递属性(下文[attribute => 'something']地图上所传递的标量,即在该示例中,以$_->{something})映射到传递的数据结构的属性和对他们进行测试。图书馆CODEREF使用定义的规则

我可以写的东西,但我真的很惊讶,我没有找到关于CPAN什么来处理它。有没有人知道图书馆做这种事情?

my @def = ([ [ attribute => 'something' ], '>', 50 ], 
      'and', 
      [ [ attribute => 'something_else' ], 'eq', 'match' ], 
     ); 

my $coderef = Reducer->new(@def); 

my @items = ({ something => 75, 
       something_else => 'match', 
       }, 
       { something => 20, 
       something_else => 'match', 
       }, 
       { something => 75, 
       something_else => 'no match', 
       }, 
       { something => 90, 
       something_else => 'match', 
       }, 
      ); 

for my $item (@items) { 
    $coderef->($item) ? say 'true' : say 'false'; 
}; 

输出:

true 
false 
false 
true 

回答

0

没有谈到这个问题,或者你确实示例代码大声疾呼由CODEREF给我来解决;您更可能找到一个将定义和项目验证为参数的子例程。

我知道有几个的那些;首先想到的是Params::Validate::validate

这将是微不足道环绕在所需的接口,尽管定义结构将从你的不同(属性的散列以验证规范,而不是阵列等)。

package Params::Validate::Reducer; 
use strict; 
use warnings; 
use Params::Validate(); 
sub new { 
    my ($class, $def) = @_; 
    sub { 
     !! eval { 
      Params::Validate::validate(@_, $def); 
      1; 
     } 
    } 
} 
+0

我倾向于编译CODEREF的唯一原因是,有将是许多检查对他们在整个项目的生命运行相对较少的规则,我希望不要有解释每次检查它的规则引用。尽管如此,可能还不成熟,我不介意放弃这个想法。您推荐的其他验证模块是什么,仅供比较之用? – Oesor

+0

我知道我已经见过其他几个人(通常分发与使用它们不相关的代码),但我不记得哪一个。 Params :: Validate当然不是速度恶魔,它的“全局选项”接口是IMO设计得非常糟糕,所以你可能最好创建你自己设想的那种编译后的coderef。 – ysth

+0

是的,在浏览Params :: Validate POD之后,我倾向于自己。这是什么真正的意思来处理只是为了能够从配置定义来看待事情,比如'如果(标量@ {$ _}> 10)'和任意数组引用'如果((uniq的地图{$ _-> {foo}} @ $ _)<3)'等等,并在评估true时运行回调。很简单,我只是感到惊讶,我没有找到可以插入的东西。 – Oesor