23rd



NAME

Symbol::Approx::Sub - Perl module for calling subroutines by approximate names!


SYNOPSIS

  use Symbol::Approx::Sub;

  sub a {
    # blah...
  }
  &aa; # executes &a if &aa doesn't exist.
  use Symbol::Approx::Sub (match => 'text_metaphone');
  use Symbol::Approx::Sub (match => 'string_approx');
  use Symbol::Approx::Sub (match => 'text_soundex');
  use Symbol::Approx::Sub (match => \&my_matcher);
  use Symbol::Approx::Sub (match => \&my_matcher, choose => \&my_chooser);


DESCRIPTION

This is _really_ stupid. This module allows you to call subroutines by _approximate_ names. Why you would ever want to do this is a complete mystery to me. It was written as an experiment to see how well I understood typeglobs and AUTOLOADing.

To use it, simply include the line:

  use Symbol::Approx::Sub;

somewhere in your program. Then each time you call a subroutine that doesn't exist in the the current package Perl will search for a subroutine with approximately the same name. The meaning of 'approximately the same' is configurable. The default is to find subroutines with the same Soundex value (as defined by Text::Soundex) as the missing subroutine. There are two other built-in matching styles using Text::MetaPhone and String::Approx. To use either of these use:

  use Symbol::Approx::Sub (match => 'text_metaphone');

or

  use Symbol::Approx::Sub (match => 'string_approx');

when using Symbol::Approx::Sub.

You can also use your own subroutine to do the matching. Your subroutine should expect to receive the name of the missing subroutine followed by a list containing all valid subroutine names and should return a list of all matching subroutines. For example:

  sub my_matcher {
    my $sub_wanted = shift;
    my @subs = @_;
    return @subs;
}

This example isn't particularly useful as it says that all subroutine names are an equally good match. To use this match subroutine in place of the standard ones, give Symbol::Approx::Sub a reference to the subroutine like this:

  use Symbol::Approx::Sub (match => \&my_matcher);

Having retrieved a list of matches, we need to select one of them to run. The default behaviour is to pick one at random, but again you can configure this behaviour by writing a subroutine. This subroutine will be passed a list of matching subroutine names and should return the name of the subroutine to run. For example:

  sub my_chooser {
    return shift;
  }

which will return the first subroutine name in the list. To make Symbol::Approx::Sub use this subroutine in place of the standard one, give Symbol::Approx::Sub a reference to the subroutine like this:

  use Symbol::Approx::Sub (choose => \&my_chooser);

You can, of course, define both a matcher and a chooser like this:

  use Symbol::Approx::Sub (match => \&my_matcher, choose => \&my_chooser);

or use you own chooser in conjunction with a standard matcher like this:

  use Symbol::Approx::Sub (match => 'text_metaphone',
                           choose => \&my_chooser);


CAVEAT

I can't stress too strongly that this will make your code completely unmaintainable and you really shouldn't use this module unless you're doing something very stupid.


ACKNOWLEDGEMENTS

This idea came to me whilst sitting in Mark-Jason Dominus' ``Tricks of the Wizards'' tutorial. In order to protect his reputation I should probably point out that just as the idea was forming in my head he clearly said that this kind of thing was a very bad idea.

Leon Brocard is clearly as mad as me as he pointed out some important bugs and helped massively with the 'fuzzy-configurability'.

Matt Freake helped by pointing out that Perl generally does what you mean, not what you think it should do.

Robin Houston spotted some nasty problems and (more importantly) supplied patches.


AUTHOR

Dave Cross <dave@dave.org.uk>

With lots of help from Leon Brocard <leon@astray.com>


SEE ALSO

perl(1).