Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Call Subroutines by Approximate Name

by davorg (Chancellor)
on Jul 26, 2000 at 18:28 UTC ( [id://24492] : CUFP . print w/replies, xml ) Need Help??

Not at all sure why anyone would want to do this - I really wrote it to see how well I understood typeglobs and AUTOLOAD :)

What it does is allow you to call subroutines in your script using names that only match approximately. Currently this means that they have the same soundex value as generated by Text::Soundex.

As I said above, there's really no good reason at all why you'd ever want to do this and it will make your code completely unmaintainable, but it's just a bit of fun. Here's a sample program showing how you'd use it.

use strict; use Sub::Approx; sub aa { print "You called 'aa'\n"; } &a;

In this example, &a doesn't exist so &aa gets called instead as 'a' and 'aa' both have the soundex value of 'A000'



I've uploaded this module to CPAN. You can get it at

package Sub::Approx; use strict; use vars qw($VERSION $AUTOLOAD); use Text::Soundex; $VERSION = '0.01'; sub import { no strict 'refs'; # WARNING: Deep magic here! my $pkg = caller(0); *{"${pkg}::AUTOLOAD"} = \&AUTOLOAD; } sub AUTOLOAD { my %cache; my @c = caller(0); my ($pkg, $sub) = $AUTOLOAD =~ /^(.*)::(.*)$/; no strict 'refs'; # WARNING: Deep magic here! foreach (keys %{"${pkg}::"}) { my $glob = $::{$_}; $glob =~ s/^\*${pkg}:://; push @{$cache{soundex($glob)}}, $glob if defined &{"*${pkg}::$glob +"}; } $sub = soundex($sub); if (exists $cache{$sub}) { my @f = @{$cache{$sub}}; $sub = "${pkg}::$f[rand @f]"; goto &$sub; } else { die "REALLY Undefined subroutine $AUTOLOAD called at $c[1] line $c +[2]\n"; } } 1;

Replies are listed 'Best First'.
RE: Call Subroutines by Approximate Name
by merlyn (Sage) on Jul 26, 2000 at 19:13 UTC

      Thanks for the idea. I chose Text::Soundex because it was available in the standard distribution.

      Of course in a perfect world, the fuzzy matching would be user configurable. Hmm...


      As of version 0.05, Sub::Approx now supports user-configurable fuzzy matching. Get it from CPAN.


      European Perl Conference - Sept 22/24 2000, ICA, London
Great for obfuscation...
by myocom (Deacon) on Jul 27, 2000 at 03:49 UTC
    You could make some *really* obfuscated Perl with this sort of technique. Or, using the Lingua::Wordnet module (q.v. the Summer 2000 TPJ), you could call subroutines by their hypernym. To use an example from the article, you could call &sneaker and have it *really* call &loafer instead. </evil>
RE: Call Subroutines by Approximate Name (poetic license)
by osfameron (Hermit) on Aug 07, 2000 at 00:13 UTC
    --Not at all sure why anyone would want to do this...

    How about for Perl poetry? Rename the module to "Poetic" perhaps playing about with the name you give it so that you can declare:

    use Poetic ':license';
    for example. The mind boggles thinking what else could be exported. Poetic 'anguish' anybody?

    On an only slightly more serious note: would it be possible for the module to call core routines by approximate names alse ?

    subb teste { prynte "testyng"; }

      If you check, sub is not a function. OTOH I see no reason why prynte would be particularly hard to do. After all you can find the core functions in the CORE:: namespace...
        Um, yes, getting a bit carried away there methinks...
        How do I get a list of the core functions though? If I do a print join "\n", keys %CORE::; this just gives  GLOBAL::.

        (Or point me to the relevant documentation...)