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> 

Reply via email to