adding in the safe mixin stuff
[gitmo/Class-MOP.git] / lib / Class / MOP / SafeMixin.pm
CommitLineData
d3cb0d4a 1
2package Class::MOP::SafeMixin;
3
4use strict;
5use warnings;
6
7our $VERSION = '0.01';
8
9sub meta {
10 require Class::MOP::Class;
11 Class::MOP::Class->initialize(blessed($_[0]) || $_[0]);
12}
13
141;
15
16__END__
17
18=pod
19
20=head1 NAME
21
22Class::MOP::SafeMixin - A meta-object for safe mixin-style composition
23
24=head1 SYNOPSIS
25
26=head1 DESCRIPTION
27
28This is a meta-object which provides B<safe> mixin-style composition
29of classes. The key word here is "safe" because we enforce a number
30of rules about mixing in which prevent some of the instability
31inherent in other mixin systems. However, it should be noted that we
32still allow you enough rope with which to shoot yourself in the foot
33if you so desire.
34
35=over 4
36
37=item *
38
39In order to mix classes together, they must inherit from a common
40superclass. This assures at least some level of similarity between
41the classes being mixed together, which should results in a more
42stable end product.
43
44The only exception to this rule is if the class being mixed in has
45no superclasses at all. In this case we assume the mixin is valid.
46
47=item *
48
49Since we enforce a common ancestral relationship, we need to be
50mindful of method and attribute conflicts. The common ancestor
51increases the potential of method conflicts because it is common
52for subclasses to override their parents methods. However, it is
53less common for attributes to be overriden. The way these are
54resolved is to use a Trait/Role-style conflict mechanism.
55
56If two classes are mixed together, any method or attribute conflicts
57will result in a failure of the mixin and a fatal exception. It is
58not possible to resolve a method or attribute conflict dynamically.
59This is because to do so would open the possibility of breaking
60classes in very subtle and dangerous ways, particularly in the area
61of method interdependencies. The amount of implementation knowledge
62which would need to be known by the mixee would (IMO) increase the
63complexity of the feature exponentially for each class mixed in.
64
65However fear not, there is a solution (see below) ...
66
67=item *
68
69Safe mixin's offer the possibility of CLOS style I<before>, I<after>
70and I<around> methods with which method conflicts can be resolved.
71
72A method, which would normally conflict, but which is labeled with
73either a I<before>, I<after> or I<around> attribute, will instead be
74combined with the original method in the way implied by the attribute.
75
76The result of this is a generalized event-handling system for classes.
77Which can be used to create things more specialized, such as plugins
78and decorators.
79
80=back
81
82=head2 What kinda crack are you on ?!?!?!?
83
84This approach may seem crazy, but I am fairly confident that it will
85work, and that it will not tie your hands unnessecarily. All these
86features have been used with certain degrees of success in the object
87systems of other languages, but none (IMO) provided a complete
88solution.
89
90In CLOS, I<before>, I<after> and I<around> methods provide a high
91degree of flexibility for adding behavior to methods, but do not address
92any concerns regarding classes since in CLOS, classes and methods are
93seperate components of the system.
94
95In Scala, mixins are restricted by their ancestral relationships, which
96results in a need to have seperate "traits" to get around this restriction.
97In addition, Scala does not seem to have any means of method conflict
98resolution for mixins (at least not that I can find).
99
100In Perl 6, the role system forces manual disambiguation which (as
101mentioned above) can cause issues with method interdependecies when
102composing roles together. This problem will grow exponentially in one
103direction with each role composed and in the other direction with the
104number of roles that role itself is composed of. The result is that the
105complexity of the system becomes unmanagable for all but very simple or
106very shallow roles. Now, this is not to say that roles are unusable, in
107fact, this feature (IMO) promotes good useage of roles by keeping them
108both small and simple. But, the same behaviors cannot be applied to
109class mixins without hitting these barriers all too quickly.
110
111The same too can be said of the original Triats system, with it's
112features for aliasing and exclusion of methods.
113
114So after close study of these systems, and in some cases actually
115implementing said systems, I have come to the see that each on it's
116own is not robust enough and that combining the best parts of each
117gives us (what I hope is) a better, safer and saner system.
118
119=head1 AUTHOR
120
121Stevan Little E<lt>stevan@iinteractive.comE<gt>
122
123=head1 COPYRIGHT AND LICENSE
124
125Copyright 2006 by Infinity Interactive, Inc.
126
127L<http://www.iinteractive.com>
128
129This library is free software; you can redistribute it and/or modify
130it under the same terms as Perl itself.
131
132=cut