我有一个函数来使用eq运算符搜索对象数组中的匹配值,如下所示:
sub find {
my ( $self, %params ) = @_;
my @entries = @{ $self->{_entries} };
if ( $params{filename} ) {
@entries = grep { $_->filename eq $params{filename} } @entries;
}
if ( $params{date} ) {
@entries = grep { $_->date eq $params{date} } @entries;
}
if ( $params{title} ) {
@entries = grep { $_->title eq $params{title} } @entries;
}
....
我还希望能够传入一个qr引用变量来代替比较,但我能想到分离比较的唯一方法就是使用if / else块,如下所示:
if (lc ref($params{whatever}) eq 'regexp') {
#use =~
} else {
#use eq
}
有更短的方法吗?由于我无法控制的原因,我使用的是Perl 5.8.8,因此无法使用智能匹配运算符。
TIA
答案 0 :(得分:5)
这是Perl,所以当然有一个CPAN模块:Match::Smart。它与Perl 5.10的智能匹配运算符非常相似,只有您键入smart_match($a, $b)
而不是$a ~~ $b
。
您可能希望与perlsyn documentation for 5.10 smartmatching进行比较,因为Match :: Smart可以处理更多情况。
否则,我没有看到任何错误:
sub smart_match {
my ($target, $param) = @_;
if (ref $param eq 'Regexp') {
return ($target =~ qr/$param/);
}
else {
return ($target eq $param);
}
}
@entries = grep { smart_match($_->date, $params{date}) } @entries;
答案 1 :(得分:0)
我不确切地知道你想要的最终结果,但你可以这样做:
for my $field (qw(filename date title)) {
my $p = $param($field};
@entries = (ref($p) eq 'regexp')
? grep { $_->$field =~ /$p/ } @entries
: grep { $_->$field eq $p } @entries;
}
或者,您甚至可以将“eq”比较转换为正则表达式,例如:
my $entry = "string to be equal to";
my $re = qr/^\Q$entry\E/;
这简化了for循环中的逻辑。