added Mouse::Meta::Class->create(_anon_class)?
[gitmo/Mouse.git] / lib / Mouse.pm
CommitLineData
eae80759 1
c3398f5b 2package Mouse;
3use strict;
4use warnings;
eae80759 5use 5.006;
eaad7dab 6use base 'Exporter';
c3398f5b 7
eae80759 8our $VERSION;
9our $PurePerl;
c3398f5b 10
eae80759 11BEGIN {
12 $VERSION = '0.12';
11ac534b 13
eae80759 14 if ($ENV{MOUSE_DEBUG}) {
15 *DEBUG = sub (){ 1 };
16 } else {
17 *DEBUG = sub (){ 0 };
18 }
11ac534b 19
eae80759 20 if (! defined $PurePerl && $ENV{MOUSE_PUREPERL} && $ENV{MOUSE_PUREPERL} =~ /^(.+)$/) {
21 $PurePerl = $1;
22 }
11ac534b 23
eae80759 24 if (! $PurePerl) {
25 local $@;
26 local $^W = 0;
27 require XSLoader;
28 $PurePerl = ! eval{ XSLoader::load(__PACKAGE__, $VERSION); 1 };
29 warn "Failed to load XS mode: $@" if $@; # && Mouse::DEBUG();
30 }
11ac534b 31}
32
c3398f5b 33use Carp 'confess';
01db075b 34use Mouse::Util 'blessed';
c3398f5b 35
306290e8 36use Mouse::Meta::Attribute;
37use Mouse::Meta::Class;
c3398f5b 38use Mouse::Object;
d60c78b9 39use Mouse::TypeRegistry;
c3398f5b 40
eaad7dab 41our @EXPORT = qw(extends has before after around blessed confess with);
42
43sub extends { Mouse::Meta::Class->initialize(caller)->superclasses(@_) }
c3398f5b 44
eaad7dab 45sub has {
46 my $meta = Mouse::Meta::Class->initialize(caller);
c3398f5b 47
eaad7dab 48 my $names = shift;
49 $names = [$names] if !ref($names);
50
51 for my $name (@$names) {
52 if ($name =~ s/^\+//) {
53 Mouse::Meta::Attribute->clone_parent($meta, $name, @_);
54 }
55 else {
56 Mouse::Meta::Attribute->create($meta, $name, @_);
c3398f5b 57 }
58 }
eaad7dab 59}
60
61sub before {
62 my $meta = Mouse::Meta::Class->initialize(caller);
63
64 my $code = pop;
65
66 for (@_) {
67 $meta->add_before_method_modifier($_ => $code);
68 }
69}
70
71sub after {
72 my $meta = Mouse::Meta::Class->initialize(caller);
73
74 my $code = pop;
75
76 for (@_) {
77 $meta->add_after_method_modifier($_ => $code);
78 }
79}
80
81sub around {
82 my $meta = Mouse::Meta::Class->initialize(caller);
83
84 my $code = pop;
85
86 for (@_) {
87 $meta->add_around_method_modifier($_ => $code);
88 }
89}
90
91sub with {
92 my $meta = Mouse::Meta::Class->initialize(caller);
93
94 my $role = shift;
4aaa2ed6 95 my $args = shift || {};
eaad7dab 96
4aaa2ed6 97 confess "Mouse::Role only supports 'with' on individual roles at a time" if @_ || !ref $args;
eaad7dab 98
99 Mouse::load_class($role);
4aaa2ed6 100 $role->meta->apply($meta, %$args);
eaad7dab 101}
102
103sub import {
e15d73d2 104 my $class = shift;
105
eaad7dab 106 strict->import;
107 warnings->import;
108
109 my $caller = caller;
110
111 my $meta = Mouse::Meta::Class->initialize($caller);
112 $meta->superclasses('Mouse::Object')
113 unless $meta->superclasses;
114
115 no strict 'refs';
116 no warnings 'redefine';
117 *{$caller.'::meta'} = sub { $meta };
118
e15d73d2 119 if (@_) {
120 __PACKAGE__->export_to_level( 1, $class, @_);
121 } else {
122 # shortcut for the common case of no type character
123 no strict 'refs';
124 for my $keyword (@EXPORT) {
125 *{ $caller . '::' . $keyword } = *{__PACKAGE__ . '::' . $keyword};
126 }
127 }
eaad7dab 128}
129
130sub unimport {
131 my $caller = caller;
132
133 no strict 'refs';
134 for my $keyword (@EXPORT) {
135 delete ${ $caller . '::' }{$keyword};
136 }
137}
c3398f5b 138
139sub load_class {
140 my $class = shift;
262801ef 141
9694b71b 142 if (ref($class) || !defined($class) || !length($class)) {
143 my $display = defined($class) ? $class : 'undef';
144 confess "Invalid class name ($display)";
145 }
c3398f5b 146
2a674d23 147 return 1 if is_class_loaded($class);
148
c3398f5b 149 (my $file = "$class.pm") =~ s{::}{/}g;
150
151 eval { CORE::require($file) };
2a674d23 152 confess "Could not load class ($class) because : $@" if $@;
c3398f5b 153
154 return 1;
155}
156
2a674d23 157sub is_class_loaded {
158 my $class = shift;
159
7ecc2123 160 return 0 if ref($class) || !defined($class) || !length($class);
161
bf134049 162 # walk the symbol table tree to avoid autovififying
163 # \*{${main::}{"Foo::"}} == \*main::Foo::
164
165 my $pack = \*::;
166 foreach my $part (split('::', $class)) {
167 return 0 unless exists ${$$pack}{"${part}::"};
168 $pack = \*{${$$pack}{"${part}::"}};
2a674d23 169 }
bf134049 170
171 # check for $VERSION or @ISA
172 return 1 if exists ${$$pack}{VERSION}
173 && defined *{${$$pack}{VERSION}}{SCALAR};
174 return 1 if exists ${$$pack}{ISA}
175 && defined *{${$$pack}{ISA}}{ARRAY};
176
177 # check for any method
178 foreach ( keys %{$$pack} ) {
179 next if substr($_, -2, 2) eq '::';
180 return 1 if defined *{${$$pack}{$_}}{CODE};
181 }
182
183 # fail
2a674d23 184 return 0;
185}
186
c3398f5b 1871;
188
189__END__
190
191=head1 NAME
192
0fff36e6 193Mouse - Moose minus the antlers
c3398f5b 194
c3398f5b 195=head1 SYNOPSIS
196
197 package Point;
6caea456 198 use Mouse; # automatically turns on strict and warnings
199
200 has 'x' => (is => 'rw', isa => 'Int');
201 has 'y' => (is => 'rw', isa => 'Int');
202
203 sub clear {
204 my $self = shift;
205 $self->x(0);
206 $self->y(0);
207 }
208
209 package Point3D;
c3398f5b 210 use Mouse;
211
6caea456 212 extends 'Point';
c3398f5b 213
6caea456 214 has 'z' => (is => 'rw', isa => 'Int');
215
8517d2ff 216 after 'clear' => sub {
217 my $self = shift;
218 $self->z(0);
219 };
c3398f5b 220
221=head1 DESCRIPTION
222
0fff36e6 223L<Moose> is wonderful.
c3398f5b 224
0fff36e6 225Unfortunately, it's a little slow. Though significant progress has been made
226over the years, the compile time penalty is a non-starter for some
227applications.
228
229Mouse aims to alleviate this by providing a subset of Moose's
230functionality, faster. In particular, L<Moose/has> is missing only a few
231expert-level features.
232
d1c1b994 233We're also going as light on dependencies as possible. Most functions we use
234from L<Scalar::Util> are copied into this dist. L<Scalar::Util> is required if
235you'd like weak references; there's simply no way to do it from pure Perl.
236L<Class::Method::Modifiers> is required if you want support for L</before>,
237L</after>, and L</around>.
238
0fff36e6 239=head2 MOOSE COMPAT
240
241Compatibility with Moose has been the utmost concern. Fewer than 1% of the
242tests fail when run against Moose instead of Mouse. Mouse code coverage is also
7e3ed32e 243over 96%. Even the error messages are taken from Moose. The Mouse code just
244runs the test suite 4x faster.
0fff36e6 245
246The idea is that, if you need the extra power, you should be able to run
8e1a28a8 247C<s/Mouse/Moose/g> on your codebase and have nothing break. To that end,
248nothingmuch has written L<Squirrel> (part of this distribution) which will act
249as Mouse unless Moose is loaded, in which case it will act as Moose.
0fff36e6 250
251Mouse also has the blessings of Moose's author, stevan.
252
253=head2 MISSING FEATURES
254
0fff36e6 255=head3 Roles
256
faa5cb70 257We're working on fixing this one! stevan has suggested an implementation
258strategy. Mouse currently ignores methods, so that needs to be fixed next.
259Roles that consist entirely of attributes may be usable in this very version.
0fff36e6 260
261=head3 Complex types
262
263User-defined type constraints and parameterized types may be implemented. Type
264coercions probably not (patches welcome).
265
266=head3 Bootstrapped meta world
267
268Very handy for extensions to the MOP. Not pressing, but would be nice to have.
269
270=head3 Modification of attribute metaclass
271
272When you declare an attribute with L</has>, you get the inlined accessors
273installed immediately. Modifying the attribute metaclass, even if possible,
274does nothing.
275
276=head3 Lots more..
277
278MouseX?
279
280=head1 KEYWORDS
c3398f5b 281
306290e8 282=head2 meta -> Mouse::Meta::Class
c3398f5b 283
284Returns this class' metaclass instance.
285
286=head2 extends superclasses
287
288Sets this class' superclasses.
289
b7a74822 290=head2 before (method|methods) => Code
291
292Installs a "before" method modifier. See L<Moose/before> or
293L<Class::Method::Modifiers/before>.
294
6beb7db6 295Use of this feature requires L<Class::Method::Modifiers>!
296
b7a74822 297=head2 after (method|methods) => Code
298
299Installs an "after" method modifier. See L<Moose/after> or
300L<Class::Method::Modifiers/after>.
301
6beb7db6 302Use of this feature requires L<Class::Method::Modifiers>!
303
b7a74822 304=head2 around (method|methods) => Code
305
306Installs an "around" method modifier. See L<Moose/around> or
307L<Class::Method::Modifiers/around>.
308
6beb7db6 309Use of this feature requires L<Class::Method::Modifiers>!
310
c3398f5b 311=head2 has (name|names) => parameters
312
313Adds an attribute (or if passed an arrayref of names, multiple attributes) to
0fff36e6 314this class. Options:
315
316=over 4
317
318=item is => ro|rw
319
320If specified, inlines a read-only/read-write accessor with the same name as
321the attribute.
322
323=item isa => TypeConstraint
324
325Provides basic type checking in the constructor and accessor. Basic types such
326as C<Int>, C<ArrayRef>, C<Defined> are supported. Any unknown type is taken to
327be a class check (e.g. isa => 'DateTime' would accept only L<DateTime>
328objects).
329
330=item required => 0|1
331
332Whether this attribute is required to have a value. If the attribute is lazy or
333has a builder, then providing a value for the attribute in the constructor is
334optional.
335
ca63d17a 336=item init_arg => Str | Undef
0fff36e6 337
ca63d17a 338Allows you to use a different key name in the constructor. If undef, the
339attribue can't be passed to the constructor.
0fff36e6 340
341=item default => Value | CodeRef
342
343Sets the default value of the attribute. If the default is a coderef, it will
344be invoked to get the default value. Due to quirks of Perl, any bare reference
345is forbidden, you must wrap the reference in a coderef. Otherwise, all
346instances will share the same reference.
347
348=item lazy => 0|1
349
350If specified, the default is calculated on demand instead of in the
351constructor.
352
353=item predicate => Str
354
355Lets you specify a method name for installing a predicate method, which checks
356that the attribute has a value. It will not invoke a lazy default or builder
357method.
358
359=item clearer => Str
360
361Lets you specify a method name for installing a clearer method, which clears
362the attribute's value from the instance. On the next read, lazy or builder will
363be invoked.
364
365=item handles => HashRef|ArrayRef
366
367Lets you specify methods to delegate to the attribute. ArrayRef forwards the
368given method names to method calls on the attribute. HashRef maps local method
369names to remote method names called on the attribute. Other forms of
370L</handles>, such as regular expression and coderef, are not yet supported.
371
372=item weak_ref => 0|1
373
374Lets you automatically weaken any reference stored in the attribute.
375
6beb7db6 376Use of this feature requires L<Scalar::Util>!
377
844fa049 378=item trigger => CodeRef
379
380Any time the attribute's value is set (either through the accessor or the constructor), the trigger is called on it. The trigger receives as arguments the instance, the new value, and the attribute instance.
381
6beb7db6 382Mouse 0.05 supported more complex triggers, but this behavior is now removed.
0fff36e6 383
384=item builder => Str
385
386Defines a method name to be called to provide the default value of the
387attribute. C<< builder => 'build_foo' >> is mostly equivalent to
388C<< default => sub { $_[0]->build_foo } >>.
389
390=item auto_deref => 0|1
391
392Allows you to automatically dereference ArrayRef and HashRef attributes in list
393context. In scalar context, the reference is returned (NOT the list length or
394bucket status). You must specify an appropriate type constraint to use
395auto_deref.
396
5253d13d 397=item lazy_build => 0|1
398
399Automatically define lazy => 1 as well as builder => "_build_$attr", clearer =>
400"clear_$attr', predicate => 'has_$attr' unless they are already defined.
401
0fff36e6 402=back
c3398f5b 403
404=head2 confess error -> BOOM
405
406L<Carp/confess> for your convenience.
407
408=head2 blessed value -> ClassName | undef
409
410L<Scalar::Util/blessed> for your convenience.
411
412=head1 MISC
413
414=head2 import
415
6caea456 416Importing Mouse will default your class' superclass list to L<Mouse::Object>.
c3398f5b 417You may use L</extends> to replace the superclass list.
418
419=head2 unimport
420
0fff36e6 421Please unimport Mouse (C<no Mouse>) so that if someone calls one of the
422keywords (such as L</extends>) it will break loudly instead breaking subtly.
c3398f5b 423
424=head1 FUNCTIONS
425
426=head2 load_class Class::Name
427
6caea456 428This will load a given C<Class::Name> (or die if it's not loadable).
c3398f5b 429This function can be used in place of tricks like
430C<eval "use $module"> or using C<require>.
431
262801ef 432=head2 is_class_loaded Class::Name -> Bool
433
434Returns whether this class is actually loaded or not. It uses a heuristic which
435involves checking for the existence of C<$VERSION>, C<@ISA>, and any
436locally-defined method.
437
c3398f5b 438=head1 AUTHOR
439
440Shawn M Moore, C<< <sartak at gmail.com> >>
441
fc9f8988 442Yuval Kogman, C<< <nothingmuch at woobling.org> >>
443
0fff36e6 444with plenty of code borrowed from L<Class::MOP> and L<Moose>
445
c3398f5b 446=head1 BUGS
447
448No known bugs.
449
450Please report any bugs through RT: email
451C<bug-mouse at rt.cpan.org>, or browse
452L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Mouse>.
453
454=head1 COPYRIGHT AND LICENSE
455
456Copyright 2008 Shawn M Moore.
457
458This program is free software; you can redistribute it and/or modify it
459under the same terms as Perl itself.
460
461=cut
462