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