use Moo::_Utils;
use B 'perlstring';
-our $VERSION = '0.009_016'; # 0.9.16
+our $VERSION = '0.091001'; # 0.91.1
$VERSION = eval $VERSION;
require Moo::sification;
my $class = shift;
strictures->import;
return if $MAKERS{$target}; # already exported into this package
- *{_getglob("${target}::extends")} = sub {
+ _install_coderef "${target}::extends" => sub {
_load_module($_) for @_;
# Can't do *{...} = \@_ or 5.10.0's mro.pm stops seeing @ISA
@{*{_getglob("${target}::ISA")}{ARRAY}} = @_;
+ if (my $old = delete $Moo::MAKERS{$target}{constructor}) {
+ delete _getstash($target)->{new};
+ Moo->_constructor_maker_for($target)
+ ->register_attribute_specs(%{$old->all_attribute_specs});
+ }
};
- *{_getglob("${target}::with")} = sub {
+ _install_coderef "${target}::with" => sub {
require Moo::Role;
Moo::Role->apply_roles_to_package($target, $_[0]);
};
$MAKERS{$target} = {};
- *{_getglob("${target}::has")} = sub {
+ _install_coderef "${target}::has" => sub {
my ($name, %spec) = @_;
- ($MAKERS{$target}{accessor} ||= do {
- require Method::Generate::Accessor;
- Method::Generate::Accessor->new
- })->generate_method($target, $name, \%spec);
$class->_constructor_maker_for($target)
->register_attribute_specs($name, \%spec);
+ $class->_accessor_maker_for($target)
+ ->generate_method($target, $name, \%spec);
};
foreach my $type (qw(before after around)) {
- *{_getglob "${target}::${type}"} = sub {
+ _install_coderef "${target}::${type}" => sub {
require Class::Method::Modifiers;
_install_modifier($target, $type, @_);
};
}
}
+sub _accessor_maker_for {
+ my ($class, $target) = @_;
+ return unless $MAKERS{$target};
+ $MAKERS{$target}{accessor} ||= do {
+ my $maker_class = do {
+ if (my $m = do {
+ if (my $defer_target =
+ (Sub::Defer::defer_info($target->can('new'))||[])->[0]
+ ) {
+ my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/);
+ $MAKERS{$pkg} && $MAKERS{$pkg}{accessor};
+ } else {
+ undef;
+ }
+ }) {
+ ref($m);
+ } else {
+ require Method::Generate::Accessor;
+ 'Method::Generate::Accessor'
+ }
+ };
+ $maker_class->new;
+ }
+}
+
sub _constructor_maker_for {
my ($class, $target, $select_super) = @_;
return unless $MAKERS{$target};
$moo_constructor = 1; # no other constructor, make a Moo one
}
};
- Method::Generate::Constructor
+ ($con ? ref($con) : 'Method::Generate::Constructor')
->new(
package => $target,
- accessor_generator => do {
- require Method::Generate::Accessor;
- Method::Generate::Accessor->new;
- },
+ accessor_generator => $class->_accessor_maker_for($target),
construction_string => (
$moo_constructor
? ($con ? $con->construction_string : undef)
: ('$class->'.$target.'::SUPER::new(@_)')
),
- subconstructor_generator => (
- $class.'->_constructor_maker_for($class,'.perlstring($target).')'
+ subconstructor_handler => (
+ ' if ($Moo::MAKERS{$class}) {'."\n"
+ .' '.$class.'->_constructor_maker_for($class,'.perlstring($target).');'."\n"
+ .' return $class->new(@_)'.";\n"
+ .' }'."\n"
),
)
->install_delayed
to make it smooth to upgrade to L<Moose> when you need more than minimal
features.
+=head1 Moo and Moose - NEW, EXPERIMENTAL
+
+If L<Moo> detects L<Moose> being loaded, it will automatically register
+metaclasses for your L<Moo> and L<Moo::Role> packages, so you should be able
+to use them in L<Moose> code without it ever realising you aren't using
+L<Moose> everywhere.
+
+Extending a L<Moose> class or consuming a L<Moose::Role> should also work.
+
+This means that there is no need for anything like L<Any::Moose> for Moo
+code - Moo and Moose code should simply interoperate without problem.
+
+However, these features are new as of 0.91.0 (0.091000) so while serviceable,
+they are absolutely certain to not be 100% yet; please do report bugs.
+
+If you need to disable the metaclass creation, add:
+
+ no Moo::sification;
+
+to your code before Moose is loaded, but bear in mind that this switch is
+currently global and turns the mechanism off entirely, so don't put this
+in library code, only in a top level script as a temporary measure while
+you send a bug report.
+
=head1 IMPORTED METHODS
=head2 new
=head2 BUILDARGS
- around BUILDARGS => sub {
- my $orig = shift;
+ sub BUILDARGS {
my ( $class, @args ) = @_;
unshift @args, "attr1" if @args % 2 == 1;
- return $class->$orig(@args);
+ return { @args };
};
Foo::Bar->new( 3 );
be handled by around albeit with a little more typing, and the author considers
augment to be a bad idea.
-The C<dump> method is not provided by default. The author suggests loading
+The C<dump> method is not provided by default. The author suggests loading
L<Devel::Dwarn> into C<main::> (via C<perl -MDevel::Dwarn ...> for example) and
using C<$obj-E<gt>$::Dwarn()> instead.
Additionally, L<Moo> supports a set of attribute option shortcuts intended to
reduce common boilerplate. The set of shortcuts is the same as in the L<Moose>
-module L<MooseX::AttributeShortcuts>. So if you:
+module L<MooseX::AttributeShortcuts> as of its version 0.009+. So if you:
package MyClass;
use Moo;
constructor. Moo does it automatically the first time ->new is called
on your class.
+=head1 SUPPORT
+
+IRC: #web-simple on irc.perl.org
+
=head1 AUTHOR
mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>