package Service; use warnings; use strict; use Module::Find 'useall'; sub create { my $class = shift; my $type = shift; my @found = useall $class; for my $plugin (@found) { if ($plugin =~ /::\Q$type\E\z/i) { return $plugin->new(@_); } } die "No $class found for type '$type'"; } sub _new { my ($class, $data) = @_; my $self = { data => $data }; return bless $self, $class; } sub populate { my $self = shift; $self->{template} =~ s/\[data\]/$self->{data}/msi; } 1; #### package Service::JSON; use warnings; use strict; use parent 'Service'; sub new { my $class = shift; my $self = $class->SUPER::_new(@_); $self->{template} = '{"data": [data]}'; return $self; } 1; #### package Service::XML; use warnings; use strict; use parent 'Service'; sub new { my $class = shift; my $self = $class->SUPER::_new(@_); $self->{template} = '[data]'; return $self; } 1; #### use warnings; use strict; use Test::More tests=>3; use_ok 'Service'; my $xml = Service->create('xml', 'xmldata'); $xml->populate; is $xml->{template}, 'xmldata', 'XML'; my $json = Service->create('json', 'jsondata'); $json->populate; is $json->{template}, '{"data": jsondata}', 'JSON';