Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

xsawyerx (8978)

xsawyerx
  (email not shown publicly)

Journal of xsawyerx (8978)

Monday December 29, 2008
12:26 PM

Figuring out error msgs is difficult sometimes

[ #38178 ]
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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.