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