package MyApp::URLFetcher::LWP;
use base qw/MyApp::URLFetcher/;
use LWP::Simple;
# define the most convenient interface you can think of
# if you need just the contents of a URL in a string, do that
sub get_url_to_str {
my $url = shift;
get($url); # our chosen interface is simple with LWP
}
####
package MyApp::URLFetcher::NetFTP;
use base qw/MyApp::URLFetcher/;
use Net::FTP;
sub get_url_to_str {
my $self = shift;
my $url = shift;
# I don't know Net::FTP
# either way, our interface is a bit harder to pull off
# with Net::FTP
# but this complexity will be in the software anyway
# it's better to hide it here
my $f = Net::FTP->new; # ...
# ...
$f->get("...");
}
####
use UNIVERSAL::require;
my $fetcher_class = choose_fetcher_class();
my $fetcher = $fetcher_class->new;
# this is the good part
# this line of code does not care what driver it's using, as
# long as the subclass of MyApp::URLFetcher is implemented correctly
# isn't polymorphism great?
my $content = $fetcher->get($url);
sub choose_fetcher_class {
foreach my $driver (qw/LWP NetFTP/){
my $class = "MyApp::URLFetcher::$driver";
# UNIVERSAL::require let's us avoid an eval
return $class if $class->require;
}
die "couldn't load any driver";
}