Skip Menu |

This queue is for tickets about the Moo CPAN distribution.

Report information
The Basics
Id: 91609
Status: rejected
Priority: 0/
Queue: Moo

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

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



Subject: Make Moo::import easier to develop loosely coupled applications and add extensions
Hi, For my projects, I'd like to define a MyProject::Class module and MyProject::Object module as base object that projects modules use in place of Moo and Moo::Object, respectively. I would like to make MyProject::Class will behave exactly like Moo. A project class that uses MyProject::Class will have all the Moo utils imported and in addition will extend MyProject::Object, which in turn inherits Moo::Object. Likewise, there is also MyProject::Role. This way, I will be able to add OO extensions specific to my projects, also have better control on future feature changes, and even switch OO systems with minimal impact on my project. However, the current Moo::import (1.003001) makes it harder to do this as it relies on caller() returns the calling package to make it a Moo class. I have been trying to use Sub::Uplevel to fool caller() to return my $target correctly in Moo::import, two levels up instead of one. But it seems to break somewhere if I have other Moo classes loaded before MyProject's Moo classes. My proposed change below will help me do this. At the same time, Feel free to bring in other solutions for discussions or implementation if this change is considered worth doing. I propose that Moo::import take an optional argument the package. For instance, package Moo; sub import { my $class = shift; my $target = shift || caller; ... } With this change, I can write MyProject::Class as follows: package MyProject::Class; require Moo; sub import { my $class = shift; my $target = shift || caller; my $extends = "$target\::extends"; # Let Moo do its magic Moo->import($target); # Make all other objects to extend MyProject:Object $extends->('MyProject::Object') unless $target eq 'MyProject::Object'; } My project Moo classes can be defined as follows: package MyProject::Work::Item; use MyProject::Class; # extends 'MyProject::Work'; has ... ...; 1; Many thanks, mytram
The recommended way to handle this is by using Import::Into. Using the latest version of Import::Into, you can do: use Import::Into; use Moo (); sub import { my $class = shift; my $target = caller; Moo->import::into(1); $class->do_more_stuff($target); } Since this already works fine, we're not going to add code to Moo to handle this.
It works perfectly. Thanks for that! On Mon Dec 23 21:27:48 2013, haarg wrote: Show quoted text
> The recommended way to handle this is by using Import::Into. Using > the latest version of Import::Into, you can do: > > use Import::Into; > use Moo (); > > sub import { > my $class = shift; > my $target = caller; > Moo->import::into(1); > $class->do_more_stuff($target); > } > > Since this already works fine, we're not going to add code to Moo to > handle this.