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