I think I would use a coercion to simplify that, and, yes, shed the unwanted attributes (accessors). Note I dropped the signatures as I don;t have the Filter module installed, but also no longer needed.

package Moo::Role::DBIConnection { use Moo::Role; use DBI; has 'dbh' => ( is => 'ro', required => 1, coerce => sub { my $args = shift; return $args if ref($args) eq 'DBI::db'; ref($args) eq 'HASH' or die 'Not a DB handle nor a hashref +'; return DBI->connect( @{$args}{qw/dsn user password options +/} ); }, ); };
## # testing package MyClass { use Moo; with 'Moo::Role::DBIConnection'; }; use Test::Most 'die'; my %args = ( dsn => 'dbi:mysql:database=mysql', user => 'ntonkin', password => undef, options => { RaiseError => 1 }, ); subtest 'With no args' => sub { dies_ok sub { my $o = MyClass->new }, 'exception on no args'; }; subtest 'With bad type' => sub { throws_ok { my $o = MyClass->new(dbh => [\%args]) } qr/Not a DB ha +ndle nor a hashref/; }; subtest 'With existing handle' => sub { my $dbh = DBI->connect( @args{qw/dsn user password options/} ); cmp_ok( $dbh->do('select count(*) from db'), '>', 0, 'Found a DB' +); my $o = new_ok('MyClass', [dbh => $dbh], 'No exception with handle + passed in'); cmp_ok( $o->dbh->do('select count(*) from db'), '>', 0, 'Found a D +B via obj'); }; subtest 'With bad params' => sub { local $args{user} = 'frobnicator'; throws_ok { my $o = MyClass->new(dbh => \%args) } qr/coercion for +"dbh" failed/; throws_ok { my $o = MyClass->new(dbh => \%args) } qr/Access denied + for user/; }; subtest 'With params' => sub { my $o = new_ok('MyClass', [dbh => \%args], 'No exception with args + hash passed in'); cmp_ok( $o->dbh->do('select count(*) from db'), '>', 0, 'Found a D +B via obj'); dies_ok sub { print $o->dsn }, 'No DSN accessor!'; }; done_testing;
Output:
$ prove -lrv 11107494.pl 11107494.pl .. # Subtest: With no args ok 1 - exception on no args 1..1 ok 1 - With no args # Subtest: With bad type ok 1 - threw Regexp ((?^:Not a DB handle nor a hashref)) 1..1 ok 2 - With bad type # Subtest: With existing handle ok 1 - Found a DB ok 2 - 'No exception with handle passed in' isa 'MyClass' ok 3 - Found a DB via obj 1..3 ok 3 - With existing handle # Subtest: With bad params ok 1 - threw Regexp ((?^:coercion for "dbh" failed)) ok 2 - threw Regexp ((?^:Access denied for user)) 1..2 ok 4 - With bad params # Subtest: With params ok 1 - 'No exception with args hash passed in' isa 'MyClass' ok 2 - Found a DB via obj ok 3 - No DSN accessor! 1..3 ok 5 - With params 1..5 ok All tests successful. Files=1, Tests=5, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.09 cusr + 0.01 csys = 0.11 CPU) Result: PASS

Hope this helps!

update: added test for bad type and moved isa check to coercion


The way forward always starts with a minimal test.

In reply to Re^6: If Perl 5 were to become Perl 7, what (backward-compatible) features would you want to see? by 1nickt
in thread If Perl 5 were to become Perl 7, what (backward-compatible) features would you want to see? by haukex

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.