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