Skip Menu |

This queue is for tickets about the MooX-ClassAttribute CPAN distribution.

Report information
The Basics
Id: 94752
Status: open
Priority: 0/
Queue: MooX-ClassAttribute

People
Owner: perl [...] toby.ink
Requestors: perl [...] toby.ink
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.010
Fixed in: (no value)



Taken from https://github.com/tobyink/p5-moox-classattribute/issues/3 ---- So, 03role.t works, but it doesn't actually test what I think is the real-world use case - where the roles and classes are in separate .pm files. If you move Foo, WithFoo, Bar, and WithBar into separate .pm files, replace them with the following in 03role.t: use WithFoo; use WithBar; And it booms: Can't locate object method "foo" via package "WithFoo" at 03role.t line 25. If I adjust the use statements to look like this: use Foo; use WithFoo; use Bar; use WithBar; Everything works.
This is a load order problem. For MooX::ClassAttribute to work with roles, it uses some rather convoluted techniques to hook code into Moo role composition and Moo->Moose inflation. This is not fun. These hooks have been parcelled off into MooX::CaptainHook to make the rest of MooX::ClassAttribute seem less evil. The hooks need to have been loaded before defining any class hoping to compose a role that includes a class attribute. In effect, this means that at least MooX::CaptainHook needs to be loaded before any of your classes. Ultimately it would be nice if Moo provided the hooks for this to happen, so that MooX::CaptainHook could just become a slim wrapper around those hooks. I can't see that happening in the near future. (Still, things are improving. There are inflation hooks for attributes now.) Until then, this is probably something I'd consider to be a "documentation bug" -- it should be noted that MooX::CaptainHook needs to be loaded early.
If that were true, wouldn't replacing "use Foo;" and "use Bar;" with "use MooX::CaptainHook" (before use(ing) Foo or Bar) silence the error? It does not seem to. On Tue Apr 15 05:48:14 2014, TOBYINK wrote: Show quoted text
> This is a load order problem. > > For MooX::ClassAttribute to work with roles, it uses some rather > convoluted techniques to hook code into Moo role composition and Moo-
> >Moose inflation. This is not fun. These hooks have been parcelled off
> into MooX::CaptainHook to make the rest of MooX::ClassAttribute seem > less evil. > > The hooks need to have been loaded before defining any class hoping to > compose a role that includes a class attribute. In effect, this means > that at least MooX::CaptainHook needs to be loaded before any of your > classes. > > Ultimately it would be nice if Moo provided the hooks for this to > happen, so that MooX::CaptainHook could just become a slim wrapper > around those hooks. I can't see that happening in the near future. > (Still, things are improving. There are inflation hooks for attributes > now.) > > Until then, this is probably something I'd consider to be a > "documentation bug" -- it should be noted that MooX::CaptainHook needs > to be loaded early.
EDIT: If that were true, wouldn't replacing "use Foo;" and "use Bar;" with "use MooX::CaptainHook" (before use(ing) WithFoo or WithBar) silence the error? It does not seem to. On Thu Apr 17 13:02:04 2014, BLUEFEET wrote: Show quoted text
> If that were true, wouldn't replacing "use Foo;" and "use Bar;" with > "use MooX::CaptainHook" (before use(ing) Foo or Bar) silence the > error? It does not seem to. > > On Tue Apr 15 05:48:14 2014, TOBYINK wrote:
> > This is a load order problem. > > > > For MooX::ClassAttribute to work with roles, it uses some rather > > convoluted techniques to hook code into Moo role composition and Moo-
> > > Moose inflation. This is not fun. These hooks have been parcelled > > > off
> > into MooX::CaptainHook to make the rest of MooX::ClassAttribute seem > > less evil. > > > > The hooks need to have been loaded before defining any class hoping > > to > > compose a role that includes a class attribute. In effect, this means > > that at least MooX::CaptainHook needs to be loaded before any of your > > classes. > > > > Ultimately it would be nice if Moo provided the hooks for this to > > happen, so that MooX::CaptainHook could just become a slim wrapper > > around those hooks. I can't see that happening in the near future. > > (Still, things are improving. There are inflation hooks for > > attributes > > now.) > > > > Until then, this is probably something I'd consider to be a > > "documentation bug" -- it should be noted that MooX::CaptainHook > > needs > > to be loaded early.
Note to others that run into this issue and find this ticket: I've found that easiest (for my application at least) work-around for this issue is to turn your role into a class and use extends instead of with. Then everything works. Its kinda lame, but hopefully this is just a temporary workaround. On Thu Apr 17 13:02:42 2014, BLUEFEET wrote: Show quoted text
> EDIT: > > If that were true, wouldn't replacing "use Foo;" and "use Bar;" with > "use MooX::CaptainHook" (before use(ing) WithFoo or WithBar) silence > the error? It does not seem to. > > On Thu Apr 17 13:02:04 2014, BLUEFEET wrote:
> > If that were true, wouldn't replacing "use Foo;" and "use Bar;" with > > "use MooX::CaptainHook" (before use(ing) Foo or Bar) silence the > > error? It does not seem to. > > > > On Tue Apr 15 05:48:14 2014, TOBYINK wrote:
> > > This is a load order problem. > > > > > > For MooX::ClassAttribute to work with roles, it uses some rather > > > convoluted techniques to hook code into Moo role composition and > > > Moo-
> > > > Moose inflation. This is not fun. These hooks have been parcelled > > > > off
> > > into MooX::CaptainHook to make the rest of MooX::ClassAttribute > > > seem > > > less evil. > > > > > > The hooks need to have been loaded before defining any class hoping > > > to > > > compose a role that includes a class attribute. In effect, this > > > means > > > that at least MooX::CaptainHook needs to be loaded before any of > > > your > > > classes. > > > > > > Ultimately it would be nice if Moo provided the hooks for this to > > > happen, so that MooX::CaptainHook could just become a slim wrapper > > > around those hooks. I can't see that happening in the near future. > > > (Still, things are improving. There are inflation hooks for > > > attributes > > > now.) > > > > > > Until then, this is probably something I'd consider to be a > > > "documentation bug" -- it should be noted that MooX::CaptainHook > > > needs > > > to be loaded early.
This might be funny to revive a 4-year old discussion, but a couple of days ago I was looking for something similar to what MooX::ClassAttribute does. And obviously hit the load-order problem with roles. There is another workaround for the bug which is demonstrated in the attached files. Simple pre-loading of the role with 'use' or 'require' is fixing the issue. classattr.pl works as expected after uncommenting 'require' in line #7.
Subject: CARole.pm
package CARole; use Moo::Role; use MooX::ClassAttribute; class_has a1 => ( is => 'rw', default => 3.1415926, ); 1;
Subject: classattr.pl
#!/usr/bin/env perl use v5.24; use lib qw<.>; package CAClass { #require CARole; use Moo; with qw<CARole>; use MooX::ClassAttribute; class_has a2 => ( is => 'rw', default => "PI", ); } say CAClass->a2; say CAClass->a1; exit;