I've found the module MooseX::Role::Flyweight a useful one for keeping a cache of objects, but I've never been happy with the way it requires you to use Class->instance(y => 'x') instead of Class->new(y => 'x') to get the new object. What if I change my mind about caching, or want to debug the code without the cache? Then I have to find all the calls in all my code and change them. What if I miss one, and call new from outside the class? So much for the cache.
I came up with this alternative approach, which seems to work. It overrides Moose's new method but still inlines the constructor.
package TestNew 0.001; use Moose; has thingy => ( required => 1, is => 'ro', ); my %obj_cache; override 'new' => sub { my ( $class, @args ) = @_; my $params = $class->BUILDARGS(@args); # from Moose::Object my $thingy = $params->{thingy}; my $cachekey = $thingy; if ( exists $obj_cache{$cachekey} ) { return $obj_cache{$cachekey}; } return $obj_cache{$thingy} = $class->_new( thingy => $thingy ); }; *Moose::Object::_new = \&Moose::Object::new; __PACKAGE__->meta->make_immutable( constructor_name => '_new' ); 1;
Other than the unfortunate need to mess around inside the Moose::Object namespace, I don't see any huge downsides, but I must admit I don't really know what I'm looking at when I poke around inside Class::MOP::Class and was wondering if others had thoughts.
Thanks,
In reply to Override new in Moose for flyweight objects by Aaronrp
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |