Figuring out error msgs is difficult sometimes

xsawyerx on 2008-12-29T17:26:38

So, I'm writing with Moose and I decide to try Roles. Why? I'm still not sure, but The Schwartz wrote about it, so it's worth testing. Instead of having a subroutine in the internal module that creates a Text::Template, I created a role for it in the main module.

[after removing irrelevant code]
Before:

package Whatever::Internal;

use Carp; use Moose; use Text::Template; # <3 mjd

...

sub build_template { my ( $self, $zone_file ) = @_; my $DOT = q{.};

$zone_file && $self->zone_file($zone_file);

my %vars = ( ip => $self->ip, ... );

my $template = Text::Template->new( SOURCE => $self->zone_file ) or croak "Couldn't construct template: $Text::Template::ERROR\n";

if ( my $result = $template->fill_in( HASH => \%vars ) ) { return $result; } else { croak "Couldn't fill in template: $Text::Template::ERROR\n"; } }
After:
package Whatever;

use Carp; use Moose::Role; use Text::Template; # <3 mjd

...

sub build_template { my ( $self, $zone_file ) = @_;

$zone_file && $self->zone_file($zone_file);

my $template = Text::Template->new( SOURCE => $self->zone_file ) or croak "Couldn't construct template: $Text::Template::ERROR\n";

if ( my $result = $template->fill_in( HASH => $self->template_vars ) ) { return $result; } else { croak "Couldn't fill in template: $Text::Template::ERROR\n"; } }

package Domains::Corp; use Moose; with 'Domains';

...

before 'build_template' => sub { my $self = shift; my $DOT = q{.};

$self->template_vars( { ip => $self->ip, ... } ); };


The trick is replacing HASH => \%vars (defined locally in that subroutine) with HASH => $self->template_vars (defined as a Role attribute) and then in the internal package (Whatever::Internal) to define the Role's attribute using a 'before'.

This might at first seem like more lines, but imagine you have Whatever::This and Whatever::That and you want to use a template for each one and to have a subroutine that renders the template for each one would be complete code replication (which is from the devil!) and so, this provides you with a faster, cleaner (and shorter) way of doing that, through a 'before' Moose clause to set up the variables for the build_template subroutine.

I don't know if this is advised by the Moose gurus (Rolsky, Little, Kogman, mst, and countless others) but it seems to work good for me so far. I would be really happy to get some input on this from people, showing me any errors or suggesting a better way I might have missed.