Skip Menu |

This queue is for tickets about the MooseX-Traits CPAN distribution.

Report information
The Basics
Id: 62166
Status: open
Priority: 0/
Queue: MooseX-Traits

People
Owner: Nobody in particular
Requestors: gshank [...] cpan.org
Cc:
AdminCc:

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



Subject: not caching anonymous classes
As of 0.10 MooseX::Traits switched to creating its own anonymous class names and is calling Moose::Meta::Class::create instead of Moose::Meta::Class::create_anon_class. Since the caching of anonymous classes happens in create_anon_class, there's no longer any caching. This creates memory leaks when using MooseX::Traits.
This just bit me pretty bad, happy to see a bug was filed for it. Now, the current code calls ->create on the meta, but passes in a package name with an incremented value so even the same class gets ::1, then ::2, ::3, etc. I have added a failing test against jrockway/moosex-traits.git which I think is the master. With some guidance I can offer a patch to fix this behavior. In my own code I created a method that uses Moose::Meta::Class->create and doesn't bother with the package name (which is working fine for me) but I'm not sure if that's what we want in MooseX::Traits. Caching inside of MooseX::Traits::Util is another option, but it would be duplicating code that exists already in Moose so seems like a bad option. I'm not sure how keeping the 'MooseX::Traits::__ANON__::SERIAL::' prefix will be possible while also caching, but I'm no super-moose-hacker.
Subject: failing-test.diff
diff --git a/t/class.t b/t/class.t index db36937..89b981c 100644 --- a/t/class.t +++ b/t/class.t @@ -46,9 +46,15 @@ my $class; lives_ok { $class = new_class_with_traits( 'Class' => 'Trait', 'Another::Trait' ); } 'new_class_with_traits works'; - +diag($class->name); ok $class; +my $class2; +lives_ok { + $class2 = new_class_with_traits( 'Class' => 'Trait', 'Another::Trait' ); +} 'same class definition'; +is $class->name, $class2->name, 'same meta class'; + my $instance = $class->name->new( foo => '42', bar => '24' ); is $instance->foo, 42; is $instance->bar, 24;
Looking at the code I can't see any reason why it needs its own __ANON__ prefix for the classes so I took that out and changed the code to create_anon_class. This seems to be working fine and does properly cache. Attached is a patch that I believe works out.
Subject: leak-fix.diff
diff --git a/lib/MooseX/Traits/Util.pm b/lib/MooseX/Traits/Util.pm index 9dfdf96..4420d49 100644 --- a/lib/MooseX/Traits/Util.pm +++ b/lib/MooseX/Traits/Util.pm @@ -65,8 +65,8 @@ sub new_class_with_traits { my $meta; @traits = resolve_traits($class, @traits); if (@traits) { - $meta = $class->meta->create( - join(q{::} => 'MooseX::Traits::__ANON__::SERIAL', ++$anon_serial), + $meta = $class->meta->create_anon_class( + #join(q{::} => 'MooseX::Traits::__ANON__::SERIAL', ++$anon_serial), superclasses => [ $class->meta->name ], roles => \@traits, cache => 1, diff --git a/t/class.t b/t/class.t index db36937..ffda648 100644 --- a/t/class.t +++ b/t/class.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 6; +use Test::More tests => 8; use Test::Exception; use MooseX::Traits; # for "no warnings ..." @@ -49,6 +49,12 @@ lives_ok { ok $class; +my $class2; +lives_ok { + $class2 = new_class_with_traits( 'Class' => 'Trait', 'Another::Trait' ); +} 'same class definition'; +is $class->name, $class2->name, 'same meta class'; + my $instance = $class->name->new( foo => '42', bar => '24' ); is $instance->foo, 42; is $instance->bar, 24;
Any solution to this needs to take into account jrockway's comments on https://rt.cpan.org/Ticket/Display.html?id=59284