Skip to content

Instantly share code, notes, and snippets.

@hesco
Created March 16, 2013 16:19
Show Gist options
  • Save hesco/5177119 to your computer and use it in GitHub Desktop.
Save hesco/5177119 to your computer and use it in GitHub Desktop.
I am writing a module (App::DB::Backup, which uses Moose) which `extends 'App::Base', 'App::DB';` App::DB also `extends 'App::Base';` (which both also use Moose). One of the new module's attributes has a default which wants to use a ->cfg attribute provided by the ::Base class. But trying to instantiate my new class gives me a 'Attribute (cfg) d…
-----------------------------
the errors I am seeing
-----------------------------
$ perl t/9999-app-db-backup.t
# Testing App::DB::Backup
ok 1 - use App::DB::Backup;
Attribute (cfg) does not pass the type constraint because: Validation failed for 'Config::Simple' with value undef (not isa Config::Simple) at /usr/local/lib/perl/5.10.1/Moose/Meta/Attribute.pm line 1274
Moose::Meta::Attribute::verify_against_type_constraint('Moose::Meta::Attribute=HASH(0x9c3dd98)', undef, 'instance', 'App::DB::Backup=HASH(0x9ce6f10)') called at /usr/local/lib/perl/5.10.1/Moose/Meta/Attribute.pm line 1261
Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attribute=HASH(0x9c3dd98)', undef, 'App::DB::Backup=HASH(0x9ce6f10)') called at /usr/local/lib/perl/5.10.1/Moose/Meta/Attribute.pm line 531
Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Attribute=HASH(0x9c3dd98)', 'Moose::Meta::Instance=HASH(0x9cf8058)', 'App::DB::Backup=HASH(0x9ce6f10)', 'HASH(0x97ca698)') called at /usr/local/lib/perl/5.10.1/Class/MOP/Class.pm line 525
Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x9a110f8)', 'HASH(0x97ca698)') called at /usr/local/lib/perl/5.10.1/Class/MOP/Class.pm line 498
Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x9a110f8)', 'HASH(0x97ca698)') called at /usr/local/lib/perl/5.10.1/Moose/Meta/Class.pm line 274
Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x9a110f8)', 'HASH(0x97ca698)') called at /usr/local/lib/perl/5.10.1/Moose/Object.pm line 28
Moose::Object::new('App::DB::Backup', 'HASH(0x942e2d0)') called at t/9999-app-db-backup.t line 13
# Tests were run but no plan was declared and done_testing() was not seen.
-----------------------------
t/9999-app-db-backup.t
-----------------------------
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use lib qw( /home/hesco/sandbox/App/lib );
use App::DB::Backup;
diag( "Testing App::DB::Backup" );
use_ok( 'App::DB::Backup' );
my $ini = '/etc/app/db_backups.ini';
my $bu = App::DB::Backup->new({
config_files => [ $ini ],
});
isa_ok( $bu, 'App::DB::Backup' );
isa_ok( $bu->file_util, 'File::Util' );
isa_ok( $bu->dbh, 'DBI::db' );
done_testing();
exit;
-----------------------------
lib/App/DB.pm
-----------------------------
package App::DB;
use Moose;
use DBI;
use Data::Dumper;
use lib qw( lib );
# use App::Base;
extends 'App::Base';
# Connect to a database server
sub connect {
my $self = shift;
my $db = shift;
# print STDERR "->connect() says that \$db is: " . Dumper(\$db);
my $db_driver = $db->{'db_driver'};
my $host_name = $db->{'db_host'};
my $db_name = $db->{'db_name'};
my $USER = $db->{'db_user'};
my $PASSWORD = $db->{'db_pw'};
my $dsn = "DBI:$db_driver:host=$host_name;database=$db_name";
if($db->{'db_ssl'}){
$dsn .= ';sslmode=require';
}
print "dsn: $dsn, user: $USER, pw: $PASSWORD \n"
if($db->{'db_debug'});
my @caller = caller();
return (DBI->connect($dsn,$USER,$PASSWORD,
{PrintError => 0, RaiseError => 1}))
or print STDERR Dumper( \@caller );
}
1; # End of App::DB
-----------------------------
lib/App/Base.pm
-----------------------------
package App::Base;
use Moose;
use Carp;
use Data::Dumper;
use File::Path qw( mkpath );
use Config::Simple::Extended;
use lib qw( lib );
use App::DB;
has 'debug' => (
is => 'rw',
isa => 'Int',
);
has 'cfg' => (
is => 'rw',
isa => 'Config::Simple',
builder => '_build_cfg',
);
has 'config_files' => (
is => 'rw',
isa => 'ArrayRef[Str]',
);
# required => 1,
has 'configuration' => (
is => 'rw',
isa => 'Config::Simple',
);
has 'dbh' => (
is => 'rw',
isa => 'DBI::db',
lazy_build => 1,
);
sub _build_cfg {
my $self = shift;
# warn '->_build_cfg gets a $self object: ' . Dumper( $self );
if(defined($self->configuration)){
return $self->configuration;
} elsif(defined($self->config_files)){
print STDERR "We have a config_files key which includes: " .
Dumper( $self->config_files )
if( $self->debug );
my $cfg;
undef($cfg);
foreach my $file (@{$self->config_files}){
print "Now applying $file to configuration hash \n"
if( $self->debug );
$cfg = Config::Simple::Extended->inherit({
debug => $self->debug,
base_config => $cfg,
filename => $file });
}
print Dumper( $cfg->get_block("paths") )
if( $self->debug );
return $cfg;
} else {
my @caller = caller();
die "App::Base's constructor invoked with no Confirguration File.\n"
. Dumper( $self, \@caller );
}
}
sub _build_dbh {
my $self = shift;
my $db = $self->cfg->get_block('db');
my $dbh = App::DB->connect($db);
return $dbh;
}
1; # End of App::Base
-----------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment