比较和验证数据结构

sim*_*one 5 perl

我必须像这样检查hashrefs

{ foo => 65, bar => 20, baz => 15 }
Run Code Online (Sandbox Code Playgroud)

对表达这样的条件的hashrefs的arrayref

[
 { foo => { "<=" => 75 } },
 { bar => { "==" => 20 } },
 { baz => { ">=" => 5 } },
]
Run Code Online (Sandbox Code Playgroud)

如果满足所有条件,则返回真值.

两个数据结构都没有预先确定.一个是通过解析数据库中的字符串而构建的,另一个是通过解析用户输入来构建的.

在上面的例子中,我会返回true,但如果我检查hashref

[
 { foo => { "<=" => 60 } },
 { bar => { "==" => 20 } },
 { baz => { ">=" => 5 } },
]
Run Code Online (Sandbox Code Playgroud)

我会返回false,因为第一个hashref中的foo不是<= 60.

问题是:这样做的最佳策略是什么?

我在想

  • 通过eval构建一系列子参数
  • 检查5个不同的预建subrefs中的适当的一个(每个案例一个>,<,<=,> =和==)

我完全走错了路吗?如果没有,最好的,评估或预建的功能是什么?

我已经研究过Params :: Validate,但是我担心它会产生大量开销,而且无论如何我都必须构建回调.

TLP*_*TLP 7

请改用代码引用,您就可以使用验证器.我简化了你的条件结构.除非你有重复的散列键,否则不需要在那里有额外的数组级别,我认为你没有.

简单化sub { $_[0] <= 75 }将简单地比较参数的第一个值.默认情况下,子例程中计算的最后一个值将是其返回值.

use v5.10;
use strict;
use warnings;

my $in = { foo => 65, bar => 21, baz => 15 };

my $ref = {
    foo => sub { $_[0] <= 75 } ,
    bar => sub { $_[0] == 20 } ,
    baz => sub { $_[0] >= 5 } ,
};

for my $key (keys %$in) {
    if ($ref->{$key}($in->{$key})) {
        say "$key : Valid";
    } else {
        say "$key : Invalid";
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

bar : Invalid
baz : Valid
foo : Valid
Run Code Online (Sandbox Code Playgroud)