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