Here at the BBC, we have a '1 in 10' policy. Ten percent of our time is recommended to be spent on personal projects which are not our work project, but which may in some way prove useful to our work project. As a result, today I am continuing work on Bermuda. Here's the basic interface:
use Bermuda; my $bermuda = Bermuda->new( { islands => 't/data', # config files perl => 't/bermuda', # where the Perl gets written to base => 'My::Bermuda', # name of our base class } ); # read the config and write the files $bermuda->swim;
And later ...
use My::AddressBook::Bermuda; my $data = My::AddressBook::Bermuda->fetch_data( $address_book );
All tests pass (except POD :) and that generates pretty rich data structures. The reason for specifying a base class is to allow applications to be deployed without requiring Bermuda to be installed.
I'd actually like the final interface to look more like this:
use My::Bermuda; my $ab_data = My::Bermuda->fetch_data( $address_book ); my $card_data = My::Bermuda->fetch_data( $card );
The problem is that this fails since we require alternate data representations (such as a paged set) for each object. Note that this is not for alternate views. Fetching the data and rendering the data are cleanly separated here. As a result, I think I'll go with something like this:
use My::Bermuda; # one page of data my $ab_paged_data = My::Bermuda->fetch_data( ab_paged => $address_book_page ); # all data my $ab_data = My::Bermuda->fetch_data( address_book => $address_book );
Because of how I've striven to separate everything out nicely, the Bermuda.pm package is ridiculously simple. Here's the full code, minus POD:
package Bermuda; use warnings; use strict; use Carp 'croak'; use File::Find (); use Bermuda::Parser; use Bermuda::Writer; our $VERSION = '0.02'; sub new { my ( $class, $arg_for ) = @_; my $self = bless { islands => $arg_for->{islands}, base => $arg_for->{base}, perl => $arg_for->{perl}, } => $class; return $self; } sub islands { shift->{islands} } sub base { shift->{base} } sub perl { shift->{perl} } sub swim { my $self = shift; my @islands = $self->_find_islands; my $parser = Bermuda::Parser->new; $parser->read(@islands); my $writer = Bermuda::Writer->new( { base => $self->base, perl => $self->perl, parser => $parser, } ); $writer->write; return $self; } sub _find_islands { my $self = shift; my @islands; File::Find::find( { no_chdir => 1, wanted => sub { if ( /\.bmd\z/ ) { push @islands => $File::Find::name; } } }, $self->islands, ); return @islands } 1;
I need a fair amount more data validation, but so far, it's pretty good. Now on to the XML generation.