4 # ABSTRACT: use Moose or Mouse modules
9 our $PREFERRED = $ENV{'ANY_MOOSE'};
15 # Any::Moose gives you strict and warnings (but only the first time, in case
16 # you do something like: use Any::Moose; no strict 'refs')
17 if (!defined(_backer_of($pkg))) {
22 # first options are for Mo*se
23 unshift @_, 'Moose' if !@_ || ref($_[0]);
25 while (my $module = shift) {
26 my $options = @_ && ref($_[0]) ? shift : [];
28 $options = $self->_canonicalize_options(
34 $self->_install_module($options);
37 # give them any_moose too
39 *{$pkg.'::any_moose'} = \&any_moose;
46 my $backer = _backer_of($pkg);
48 eval "package $pkg;\n"
49 . '$backer->unimport(@_);';
55 return 'Mouse' if $INC{'Mouse.pm'}
56 && Mouse::Meta::Class->_metaclass_cache($pkg);
57 return 'Mouse::Role' if $INC{'Mouse/Role.pm'}
58 && Mouse::Meta::Role->_metaclass_cache($pkg);
60 if (_is_moose_loaded()) {
61 my $meta = Class::MOP::get_metaclass_by_name($pkg);
63 return 'Moose::Role' if $meta->isa('Moose::Meta::Role');
64 return 'Moose' if $meta->isa('Moose::Meta::Class');
71 sub _canonicalize_options {
76 if (ref($args{options}) eq 'HASH') {
77 %options = %{ $args{options} };
81 imports => $args{options},
85 $options{package} = $args{package};
86 $options{module} = any_moose($args{module}, $args{package});
95 my $module = $options->{module};
96 (my $file = $module . '.pm') =~ s{::}{/}g;
100 eval "package $options->{package};\n"
101 . '$module->import(@{ $options->{imports} });';
105 my $fragment = _canonicalize_fragment(shift);
106 my $package = shift || caller;
108 # Mouse gets first dibs because it doesn't introspect existing classes
110 if ((_backer_of($package)||'') =~ /^Mouse/) {
111 $fragment =~ s/^Moose/Mouse/;
115 return $fragment if (_backer_of($package)||'') =~ /^Moose/;
117 # If we're loading up the backing class...
118 if ($fragment eq 'Moose' || $fragment eq 'Moose::Role') {
120 $PREFERRED = _is_moose_loaded() ? 'Moose' : 'Mouse';
122 (my $file = $PREFERRED . '.pm') =~ s{::}{/}g;
126 $fragment =~ s/^Moose/Mouse/ if mouse_is_preferred();
131 Carp::croak("Neither Moose nor Mouse backs the '$package' package.");
135 my ($class_name) = @_;
136 return Class::MOP::load_class($class_name) if moose_is_preferred();
137 return Mouse::load_class($class_name);
140 sub is_class_loaded {
141 my ($class_name) = @_;
142 return Class::MOP::is_class_loaded($class_name) if moose_is_preferred();
143 return Mouse::is_class_loaded($class_name);
146 sub moose_is_preferred { $PREFERRED eq 'Moose' }
147 sub mouse_is_preferred { $PREFERRED eq 'Mouse' }
149 sub _is_moose_loaded { !!$INC{'Class/MOP.pm'} }
151 sub is_moose_loaded {
152 Carp::carp("Any::Moose::is_moose_loaded is deprecated. Please use Any::Moose::moose_is_preferred instead");
153 goto \&_is_moose_loaded;
156 sub _canonicalize_fragment {
157 my $fragment = shift;
159 return 'Moose' if !defined($fragment);
161 # any_moose("X::Types") -> any_moose("MooseX::Types")
162 $fragment =~ s/^X::/MooseX::/;
164 # any_moose("::Util") -> any_moose("Moose::Util")
165 $fragment =~ s/^::/Moose::/;
167 # any_moose("Mouse::Util") -> any_moose("Moose::Util")
168 $fragment =~ s/^Mouse(X?)\b/Moose$1/;
170 # any_moose("Util") -> any_moose("Moose::Util")
171 $fragment =~ s/^(?!Moose)/Moose::/;
173 # any_moose("Moose::") (via any_moose("")) -> any_moose("Moose")
174 $fragment =~ s/^Moose::$/Moose/;
185 Any::Moose - use Moose or Mouse modules
197 # uses Moose if it's loaded, Mouse otherwise
202 package Other::Class;
205 # uses Moose::Util::TypeConstraints if the class has loaded Moose,
206 # Mouse::Util::TypeConstraints otherwise.
207 use Any::Moose '::Util::TypeConstraints';
211 package My::Meta::Class;
214 # uses subtype from Moose::Util::TypeConstraints if the class loaded Moose,
215 # subtype from Mouse::Util::TypeConstraints otherwise.
216 # similarly for Mo*se::Util's does_role
218 '::Util::TypeConstraints' => ['subtype'],
219 '::Util' => ['does_role'],
223 use Any::Moose 'X::Types';
225 # gives you the right class name depending on which Mo*se was loaded
226 extends any_moose('::Meta::Class');
230 Actual documentation is forthcoming, once we solidify all the bits of the API.
231 The examples above are very likely to continue working.
235 Shawn M Moore <sartak@bestpractical.com>
236 Florian Ragwitz <rafl@debian.org>
237 Stevan Little <stevan@iinteractive.com>
238 Tokuhiro Matsuno <tokuhirom@gmail.com>
240 =head1 COPYRIGHT AND LICENSE
242 This software is copyright (c) 2009 by Best Practical Solutions.
244 This is free software; you can redistribute it and/or modify it under
245 the same terms as perl itself.