package StupidAutoloader; use strict; use warnings; use Carp; our %Classes; our $AUTOLOAD; *UNIVERSAL::AUTOLOAD = sub { my $proto = $_[0]; my $class = ref($proto) || $proto; my $method_name = $AUTOLOAD; die "Could not determine method name." if not defined $method_name; $method_name =~ /::(\w+)$/ or die; $method_name = $1; croak "Could not find method new() in package '$class'." if ref($proto) or exists $INC{$class} or (not _in_hierarchy(\%Classes, $class) and not exists $Classes{'*'}); eval "use $class;"; croak "Error loading module '$class': $@" if $@; no strict 'refs'; goto &{"${class}::${method_name}"}; }; sub import { my $class = shift; my @hierarchies = @_; foreach (@hierarchies) { $Classes{$_} = undef; } } sub unimport { my $class = shift; my @hierarchies = @_; if (not @hierarchies) { %Classes = (); } foreach (@hierarchies) { delete $Classes{$_}; } } sub _in_hierarchy { my $h = shift; my $c = shift; return 1 if exists $h->{$c}; my @levels = split /::/, $c; my $accum; foreach (@levels) { $accum .= $_; return 1 if exists $h->{"${accum}::*"} } return 0; } 1;