Peter,
sounds like a reasonable wish ( see attached patch ;-)
Allowing developers to specify their own matching module instead of the
ones we pre-cooked is a little tricky since every module uses a
different name for the match method and other peculiarities.
We could allow for:
use Net::DLAP::FilterMatch Text::Soundex=>soundex;
or
use Net::DLAP::FilterMatch qw(Text::Soundex::soundex);
But this becomes rather messy given the differences between modules, if
someone really wants something special he can always override the
_cis_approxMatch sub. What do you think ?
Cheers,
Hans
Peter Marschall wrote:
Hi,
[.....]
I guess specifying a new match is not possible.
What we might try is to convert a match a la
(sn~=Schm*dt) to a regex (i.e. add a . before the *)
but that might get very tricky with the subtleties of regexes
and LDAP filters.
So be better leave it the plain regex we have now.
I am not absolutely happy with the way how the
approx modules are selected.
I can imagine cases where I have all three installed
but want to do approx matching using metaphone.
(or even using regexes ;-)
Maybe you can use the idea we used in Authen-SASL
(get it from the same source as perl-ldap SVN ;-)
There we used the import() routine of the module to
choose the backend.
Using this idea for Net::LDAP::FilterMatch might allow
to write
use Net::DLAP::FilterMatch qw/Text::Soundex/;
to use Text::Soundex as approx matching backend.
What do you think of it ?
CU
PEter
Index: FilterMatch.pm
===================================================================
--- FilterMatch.pm (revision 485)
+++ FilterMatch.pm (working copy)
@@ -12,13 +12,28 @@
package Net::LDAP::FilterMatch;
+sub import {
+ shift;
+
+ push (@_,@Net::LDAP::Filter::approxMatchers) unless @_;
+ @Net::LDAP::Filter::approxMatchers = grep { eval "require $_" } @_ ;
+
+}
+
use Net::LDAP::Filter;
use Net::LDAP::Schema;
-$VERSION = '0.15';
+$VERSION = '0.16';
package Net::LDAP::Filter;
+use vars qw($VERSION @Plugins);
[EMAIL PROTECTED] = qw(
+ String::Approx
+ Text::Metaphone
+ Text::Soundex
+);
+
sub _filterMatch($@);
sub _cis_equalityMatch($@);
@@ -258,25 +273,22 @@
my $assertion=shift;
my $op=shift;
- if (eval ("require String::Approx")){
- #print "using String::Approx\n";
- return String::Approx::amatch($assertion, @_) ? 1 : 0;
-
+ foreach (@approxMatchers) {
+ # print "using $_\n";
+ if (/String::Approx/){
+ return String::Approx::amatch($assertion, @_) ? 1 : 0;
+ }
+ elsif (/Text::Metaphone/){
+ my $metamatch = Text::Metaphone::Metaphone($assertion);
+ return grep((Text::Metaphone::Metaphone($_) eq $metamatch), @_) ? 1 : 0;
+ }
+ elsif (/Text::Soundex/){
+ my $smatch = Text::Soundex::soundex($assertion);
+ return grep((Text::Soundex::soundex($_) eq $smatch), @_) ? 1 : 0;
+ }
}
- elsif (eval ("require Text::Metaphone")){
- #print "using Text::Metaphone\n";
- my $metamatch = Text::Metaphone::Metaphone($assertion);
- return grep((Text::Metaphone::Metaphone($_) eq $metamatch), @_) ? 1 : 0;
- }
- elsif (eval ("require Text::Soundex")){
- #print "using Text::Soundex\n";
- my $smatch = Text::Soundex::soundex($assertion);
- return grep((Text::Soundex::soundex($_) eq $smatch), @_) ? 1 : 0;
- }
- else{
- #we really have nothing, use plain regexp
- return grep(/^$assertion$/i, @_) ? 1 : 0;
- }
+ #we really have nothing, use plain regexp
+ return grep(/^$assertion$/i, @_) ? 1 : 0;
}
1;
@@ -333,7 +345,19 @@
=back
+For approximate matching like (cn~=Schmidt) there are several modules that can
+be used. By default the following modules will be tried in this order:
+ String::Approx
+ Text::Metaphone
+ Text::Soundex
+
+If none of these modules is found it will fall back on a simple regexp
algorithm.
+
+If you want to specifically use one implementation only, simply do
+
+ use Net::LDAP::FilterMatch qw(Text::Soundex);
+
=head1 SEE ALSO
L<Net::LDAP::Filter>