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