[Dbix-class] DBIC and Moo woes

Graham Knop haarg at haarg.org
Mon Oct 6 23:10:54 GMT 2014


On Thu, Oct 2, 2014 at 2:24 PM, Aran Deltac <bluefeet at gmail.com> wrote:
> I've abstracted out my work to something more general.  I'm going to copy
> over and run the entire DBIC test suite against it and see what fails.
> There is some magic in the load_components bit as it uses some Moo internals
> to do the Moo extends and with properly.  Just posting here if anyone is
> curious.
>
> https://github.com/bluefeet/DBICx-Moo
>
> Aran
>
> On Wed, Oct 1, 2014 at 7: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?
>> 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.
>>
>> 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.
>>
>> 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.
>>
>> 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

Generally, using DBIC with Moo should be as simple as `use Moo;
extends "DBIx::Class...";`
There appears to be a few bugs there to fix, but I'd prefer to
approach things from
that angle, making a special Moo+DBIC module unnecessary.

There's a few things I don't like about your implementation.  Reaching
into Moo's internals
like that is particularly gross.  If you want to change superclasses
or compose roles, the
correct interface to use is calling the class's "extends" or "with"
subs.  Also, trying to detect
role vs class is generally a bad idea.  It should be handled as a
separate interface.  Trying to
detect that also resulted in loading Moose, with the speed hit and XS
requirement that implies.

Personally, I don't see much value in trying to adapt Moo to use the
__PACKAGE__->method
style syntax for anything.  If I wanted to mesh the two styles, I'd go
for sugar like
DBIx::Class::Candy provides.  The automatic prefixing seems to be the
only thing provided by
load_components, and that is just as easily done in a helper sub.



More information about the DBIx-Class mailing list