uploin
[gitmo/Moose.git] / lib / Moose.pm
1
2 use lib '/Users/stevan/Projects/CPAN/Class-MOP/Class-MOP/lib';
3
4 package Moose;
5
6 use strict;
7 use warnings;
8
9 our $VERSION = '0.02';
10
11 use Scalar::Util 'blessed', 'reftype';
12 use Carp         'confess';
13 use Sub::Name    'subname';
14
15 use UNIVERSAL::require;
16
17 use Class::MOP;
18
19 use Moose::Meta::Class;
20 use Moose::Meta::SafeMixin;
21 use Moose::Meta::Attribute;
22
23 use Moose::Object;
24 use Moose::Util::TypeConstraints ':no_export';
25
26 # bootstrap the mixin module
27 Moose::Meta::SafeMixin::mixin(Moose::Meta::Class->meta, 'Moose::Meta::SafeMixin');
28
29 sub import {
30         shift;
31         my $pkg = caller();
32         
33         # we should never export to main
34         return if $pkg eq 'main';
35         
36         Moose::Util::TypeConstraints->import($pkg);
37
38         my $meta;
39         if ($pkg->can('meta')) {
40                 $meta = $pkg->meta();
41                 (blessed($meta) && $meta->isa('Class::MOP::Class'))
42                         || confess "Whoops, not møøsey enough";
43         }
44         else {
45                 $meta = Moose::Meta::Class->initialize($pkg => (
46                         ':attribute_metaclass' => 'Moose::Meta::Attribute'
47                 ));
48                 $meta->add_method('meta' => sub {
49                         # re-initialize so it inherits properly
50                         Moose::Meta::Class->initialize($pkg => (
51                                 ':attribute_metaclass' => 'Moose::Meta::Attribute'
52                         ));                     
53                 })              
54         }
55         
56         # NOTE:
57         # &alias_method will install the method, but it 
58         # will not name it with 
59         
60         # handle superclasses
61         $meta->alias_method('extends' => subname 'Moose::extends' => sub { 
62             $_->require for @_;
63             $meta->superclasses(@_) 
64         });
65         
66         # handle mixins
67         $meta->alias_method('with' => subname 'Moose::with' => sub { $meta->mixin($_[0]) });    
68         
69         # handle attributes
70         $meta->alias_method('has' => subname 'Moose::has' => sub { 
71                 my ($name, %options) = @_;
72                 if (exists $options{is}) {
73                         if ($options{is} eq 'ro') {
74                                 $options{reader} = $name;
75                         }
76                         elsif ($options{is} eq 'rw') {
77                                 $options{accessor} = $name;                             
78                         }                       
79                 }
80                 if (exists $options{isa}) {
81                         if (reftype($options{isa}) && reftype($options{isa}) eq 'CODE') {
82                                 $options{type_constraint} = $options{isa};
83                         }
84                         else {
85                                 $options{type_constraint} = Moose::Util::TypeConstraints::subtype(
86                                         Object => Moose::Util::TypeConstraints::where { $_->isa($options{isa}) }
87                                 );                      
88                         }
89                 }
90                 $meta->add_attribute($name, %options) 
91         });
92
93         # handle method modifers
94         $meta->alias_method('before' => subname 'Moose::before' => sub { 
95                 my $code = pop @_;
96                 $meta->add_before_method_modifier($_, $code) for @_; 
97         });
98         $meta->alias_method('after'  => subname 'Moose::after' => sub { 
99                 my $code = pop @_;
100                 $meta->add_after_method_modifier($_, $code) for @_;
101         });     
102         $meta->alias_method('around' => subname 'Moose::around' => sub { 
103                 my $code = pop @_;
104                 $meta->add_around_method_modifier($_, $code) for @_;    
105         });     
106
107         # make sure they inherit from Moose::Object
108         $meta->superclasses('Moose::Object')
109        unless $meta->superclasses();
110
111         # we recommend using these things 
112         # so export them for them
113         $meta->alias_method('confess' => \&Carp::confess);                      
114         $meta->alias_method('blessed' => \&Scalar::Util::blessed);                              
115 }
116
117 1;
118
119 __END__
120
121 =pod
122
123 =head1 NAME
124
125 Moose - Moose, it's the new Camel
126
127 =head1 SYNOPSIS
128
129   package Point;
130   use Moose;
131         
132   has 'x' => (isa => Int(), is => 'rw');
133   has 'y' => (isa => Int(), is => 'rw');
134   
135   sub clear {
136       my $self = shift;
137       $self->x(0);
138       $self->y(0);    
139   }
140   
141   package Point3D;
142   use Moose;
143   
144   extends 'Point';
145   
146   has 'z' => (isa => Int());
147   
148   after 'clear' => sub {
149       my $self = shift;
150       $self->{z} = 0;
151   };
152   
153 =head1 CAVEAT
154
155 This is a B<very> early release of this module, it still needs 
156 some fine tuning and B<lots> more documentation. I am adopting 
157 the I<release early and release often> approach with this module, 
158 so keep an eye on your favorite CPAN mirror!
159
160 =head1 DESCRIPTION
161
162 Moose is an extension of the Perl 5 object system. 
163
164 =head2 Another object system!?!?
165
166 Yes, I know there has been an explosion recently of new ways to 
167 build object's in Perl 5, most of them based on inside-out objects, 
168 and other such things. Moose is different because it is not a new 
169 object system for Perl 5, but instead an extension of the existing 
170 object system.
171
172 Moose is built on top of L<Class::MOP>, which is a metaclass system 
173 for Perl 5. This means that Moose not only makes building normal 
174 Perl 5 objects better, but it also provides the power of metaclass 
175 programming.
176
177 =head2 What does Moose stand for??
178
179 Moose doesn't stand for one thing in particular, however, if you 
180 want, here are a few of my favorites, feel free to contribute 
181 more :)
182
183 =over 4
184
185 =item Make Other Object Systems Envious
186
187 =item Makes Object Orientation So Easy
188
189 =item Makes Object Orientation Spiffy- Er  (sorry ingy)
190
191 =item Most Other Object Systems Emasculate
192
193 =item My Overcraft Overfilled (with) Some Eels
194
195 =item Moose Often Ovulate Sorta Early
196
197 =item Many Overloaded Object Systems Exists 
198
199 =item Moose Offers Often Super Extensions
200
201 =back
202
203 =head1 ACKNOWLEDGEMENTS
204
205 =over 4
206
207 =item I blame Sam Vilain for giving me my first hit of meta-model crack.
208
209 =item I blame Audrey Tang for encouraging that meta-crack habit in #perl6.
210
211 =item Without the love and encouragement of Yuval "nothingmuch" Kogman, 
212 this module would not be possible (and it wouldn't have a name).
213
214 =item The basis of the TypeContraints module was Rob Kinyon's idea 
215 originally, I just ran with it.
216
217 =back
218
219 =head1 BUGS
220
221 All complex software has bugs lurking in it, and this module is no 
222 exception. If you find a bug please either email me, or add the bug
223 to cpan-RT.
224
225 =head1 AUTHOR
226
227 Stevan Little E<lt>stevan@iinteractive.comE<gt>
228
229 =head1 COPYRIGHT AND LICENSE
230
231 Copyright 2006 by Infinity Interactive, Inc.
232
233 L<http://www.iinteractive.com>
234
235 This library is free software; you can redistribute it and/or modify
236 it under the same terms as Perl itself. 
237
238 =cut