[Dbix-class] DBIC and Moo woes

Graham Knop haarg at haarg.org
Mon Oct 6 22:48:31 GMT 2014


On Wed, Oct 1, 2014 at 10:21 PM, Aran Deltac <bluefeet at gmail.com> wrote:
> I've been converting a lot of @work's custom components, result, result set,
> schema, and storage classes (yes, we even have custom storage classes) to
> Moo roles and classes.
>
> I've just about completed it and have worked through a lot of issues, but am
> left with one remaining issue which I'm stumped at and have been able to
> whittle it down to a couple small examples:
>
> package FooResult;
> use Moo;
> print 'HAS BUILDARGS: ' . (FooResult->can('BUILDARGS') ? 'YES' : 'NO') .
> "\n";
> extends 'DBIx::Class::Core';
> print 'HAS BUILDARGS: ' . (FooResult->can('BUILDARGS') ? 'YES' : 'NO') .
> "\n";
>
> That prints:
> HAS BUILDARGS: YES
> HAS BUILDARGS: NO
>
> I was able to change this to YES-YES by adding Moo::Object to the front of
> my extends, which in the above example would look like:
>
> extends 'Moo::Object', 'DBIx::Class::Core';
>
> Is that the right thing to do when inheriting from a non-Moo class?

Adding Moo::Object manually like this is a supported way to override
the constructor
of whatever else you are inheriting from, and use a purely Moo style
constructor that
won't call the other parent.

That's only meant for cases where something is misbehaving, and will
break many things.
Doing it with DBIC will certainly break things s That should only be
needed if something is misbehaving.
It shouldn't be needed in your case, and I'm pretty certain it will
break things.  DBIC
does a fair amount of work in its constructors and you would be bypassing.

> Documentation on non-moo inheritance was minimal in the Moo docs, but maybe
> I missed it.  Note that I found this issue via a Moose result class which
> inherits from my Moo result base class which inherits from
> DBIx::Class::Core.  Something about that relationship structure requires
> BUILDARGS even though the involved code neither declares nor calls
> BUILDARGS.
BUILDARGS should not be required.  This is a bug in Moo.  I'm working
on a fix.  You
should be able to work around this by making sure your Moose classes are calling
__PACKAGE__->meta->make_immutable.  Another workaround would be
including *BUILDARGS = \&Moo::Object::BUILDARGS; in your Moo class.

>
> Another issue is this:
>
> package FooResult;
> use Moo;
> extends 'DBIx::Class::Core';
> has bar => ( is=>'ro' );
> FooResult->new( bar=>32 );
>
> Which then hangs with:
>
> Deep recursion on subroutine "DBIx::Class::Row::throw_exception" at
> /home/aran/local-lib/lib/perl5/DBIx/Class/Row.pm line 1416.
> Deep recursion on subroutine "DBIx::Class::Row::result_source" at
> /home/aran/local-lib/lib/perl5/DBIx/Class/Row.pm line 1568.
>
> I tried fiddling with FOREIGNBUILDARGS to see if I could produce arguments
> which made DBIC's new() happy but it was a fruitless effort.
Part of this I believe is a bug in DBIC, where a certain class of
errors can result in
deep recursion.  What the deep recursion issue is hiding is that
DBIC's ->new expects
a hashref of options, but you gave it a list.  The easiest option
would be to always pass
in options in hashref form ( FooResult->new({bar => 32}); ) but you
could also define a
FOREIGNBUILDARGS to do that transformation for you.

>
> At this point the error I am getting with the real application code is:
>
> DBIx::Class::Sims::load_sims(): Can't call method "new" on an undefined
> value at /home/aran/local-lib/lib/perl5/DBIx/Class/ResultSet.pm line 2590.
> at /home/aran/ziprecruiter/app/t/lib/Test/ZR/Schema.pm line 95
>
> Which is what lead me to the two previous examples.  As far as I can tell my
> Moo conversion is complete and there is something wrong with the argument
> processing between Moo and DBIC.

This looks like the result of bypassing DBIC's constructor by adding Moo::Object
to your extends.  The result_source isn't being initialized correctly,
because that is
done by DBIC's constructor.

>
> I'm using the latest DBIC (0.082800) and Moo (1.006).
>
> Any pointers, examples, words of wisdom, RTFMs, etc, appreciated.
>
> Thanks!
>
> _______________________________________________
> List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
> IRC: irc.perl.org#dbix-class
> SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
> Searchable Archive:
> http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk



More information about the DBIx-Class mailing list