Commit | Line | Data |
677eb158 |
1 | |
2 | package metaclass; |
3 | |
4 | use strict; |
5 | use warnings; |
6 | |
7 | use Carp 'confess'; |
8 | |
9 | our $VERSION = '0.01'; |
10 | |
11 | use Class::MOP; |
12 | |
13 | sub import { |
14 | shift; |
c9e77dbb |
15 | my $metaclass = shift || 'Class::MOP::Class'; |
677eb158 |
16 | my %options = @_; |
17 | my $package = caller(); |
18 | |
19 | ($metaclass->isa('Class::MOP::Class')) |
20 | || confess 'The metaclass must be derived from Class::MOP::Class'; |
21 | |
22 | # create a meta object so we can install &meta |
23 | my $meta = $metaclass->initialize($package => %options); |
24 | $meta->add_method('meta' => sub { |
25 | # we must re-initialize so that it |
26 | # works as expected in subclasses, |
27 | # since metaclass instances are |
28 | # singletons, this is not really a |
29 | # big deal anyway. |
30 | $metaclass->initialize($_[0] => %options) |
31 | }); |
32 | } |
33 | |
c9e77dbb |
34 | =pod |
35 | |
36 | NOTES |
37 | |
38 | Okay, the metaclass constraint issue is a bit of a PITA. |
39 | |
40 | Especially in the context of MI, where we end up with an |
41 | explosion of metaclasses. |
42 | |
43 | SOOOO |
44 | |
45 | Instead of auto-composing metaclasses using inheritance |
46 | (which is problematic at best, and totally wrong at worst, |
47 | especially in the light of methods of Class::MOP::Class |
48 | which are overridden by subclasses (try to figure out how |
49 | LazyClass and InsideOutClass could be composed, it is not |
50 | even possible)) we use a trait model. |
51 | |
52 | It will be similar to Class::Trait, except that there is |
53 | no such thing as a trait, a class isa trait and a trait |
54 | isa class, more like Scala really. |
55 | |
56 | This way we get several benefits: |
57 | |
58 | 1) Classes can be composed like traits, and it Just Works. |
59 | |
60 | 2) Metaclasses can be composed this way too :) |
61 | |
62 | 3) When solving the metaclass constraint, we create an |
63 | anon-metaclass, and compose the parent's metaclasses |
64 | into it. This allows for conflict checking trait-style |
65 | which should inform us of any issues right away. |
66 | |
67 | Misc. Details: |
68 | |
69 | Class metaclasses must be composed, but so must any |
70 | associated Attribute and Method metaclasses. However, this |
71 | is not always relevant since I should be able to create a |
72 | class which has lazy attributes, and then create a subclass |
73 | of that class whose attributes are not lazy. |
74 | |
75 | |
76 | =cut |
77 | |
677eb158 |
78 | 1; |
79 | |
80 | __END__ |
81 | |
82 | =pod |
83 | |
84 | =head1 NAME |
85 | |
86 | metaclass - a pragma for installing using Class::MOP metaclasses |
87 | |
88 | =head1 SYNOPSIS |
89 | |
90 | use metaclass 'MyMetaClass'; |
91 | |
92 | use metaclass 'MyMetaClass' => ( |
93 | ':attribute_metaclass' => 'MyAttributeMetaClass', |
94 | ':method_metaclass' => 'MyMethodMetaClass', |
95 | ); |
96 | |
97 | =head1 DESCRIPTION |
98 | |
c9e77dbb |
99 | This is a pragma to make it easier to use a specific metaclass |
100 | and it's |
101 | |
677eb158 |
102 | =head1 AUTHOR |
103 | |
104 | Stevan Little E<lt>stevan@iinteractive.comE<gt> |
105 | |
106 | =head1 COPYRIGHT AND LICENSE |
107 | |
108 | Copyright 2006 by Infinity Interactive, Inc. |
109 | |
110 | L<http://www.iinteractive.com> |
111 | |
112 | This library is free software; you can redistribute it and/or modify |
113 | it under the same terms as Perl itself. |
114 | |
115 | =cut |