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