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