immutable refacotring
[gitmo/Class-MOP.git] / lib / Class / MOP / Immutable.pm
1
2 package Class::MOP::Immutable;
3
4 1;
5
6 __END__
7
8 =pod
9
10 Okay, so here is the basic idea.
11
12 First, your metaclass must register with Class::MOP::Immutable
13 at which point an anon-class is created which will be the 
14 immutable class which your metaclass will be blessed into. 
15
16 This allows immutable versions of any metaclass to be created
17 on the fly if needed. 
18
19 NOTE:
20 Remember the immutable version of the metaclass will be used to 
21 construct/convert mutable instances into immutable versions. So 
22 it itself is a metaclass.
23
24   Class::MOP::Immutable->make_immutable_metaclass(
25       # name of the metaclass we are 
26       # making immutable
27       metaclass => 'Class::MOP::Class',
28       
29       # names of some method metaclasses
30       # which will be useful in the creation
31       # of the immutable versions
32       constructor_class => 'Class::MOP::Method::Constructor',
33       accessor_class    => 'Class::MOP::Method::Accessor',    # ?? maybe
34       
35       # options which the immutable converter
36       # will accept, not exactly sure about 
37       # this one,.. it might have to be hard 
38       # coded in some way.
39       available_options => [qw[
40           inline_accessors
41           inline_constructor
42           constructor_name
43       ]],    
44       
45       # multiple lists of things which can 
46       # be done to the metaclass .. 
47       
48       # make these methods die when called
49       disallow  => [qw[
50           add_method
51           alias_method
52           remove_method
53           add_attribute
54           remove_attribute
55           add_package_symbol
56           remove_package_symbol
57       ]],
58       
59       # memoize the value of these methods
60       memoize   => [qw[
61           class_precedence_list
62           compute_all_applicable_attributes
63           get_meta_instance            
64           get_method_map
65       ]],
66       
67       # make these methods read only
68       readonly  => [qw[
69           superclasses
70       ]],
71   );
72
73 Now, this will work just fine for singular metas, but 
74 we want this to be able to work for extensions to the 
75 metaclasses as well.
76
77 Here is how we do that:
78
79   Class::MOP::Immutable->make_immutable_metaclass(
80       # the metaclass name ...
81       metaclass => 'Moose::Meta::Class',
82       
83       # inherit the options from immutable 
84       # parent class (Class::MOP::Class)
85       inherit   => 1
86       
87       constructor_class => 'Moose::Method::Constructor',
88       accessor_class    => 'Moose::Method::Accessor',    # ?? maybe    
89       
90       disallow => [qw[
91           add_roles
92           ...
93       ]],
94       
95       memoize => [qw[
96           roles
97           ...
98       ]]    
99   );
100
101 When you specify C<inherit => 1> you are telling 
102 Class::MOP::Immutable that you want to inherit your 
103 parents options. This means that you get all their
104 and yours (perhaps some basic conflict resolution 
105 can be added here as well).
106
107 It might make sense to also allow a more granular 
108 approach such as:
109
110   inherit => {
111       disallow => 'merge',
112       memoize  => 'override',
113       readonly => 'ignore',
114   }
115
116 which would allow you to specify in more detail how 
117 you would like to handle each change. This might be 
118 more than anyone ever needs so we can probably hold 
119 off for now.
120
121 Ultimately it will be the responsibility of the 
122 author to make sure their immutable options make sense.
123
124 The reason I say this is that you could easily get 
125 carried away in the number of items you choose to 
126 memoize or such. This would not make a lot of sense, 
127 it would make more sense to memoize at the "topmost"
128 level instead, rather than all the intermediate ones.
129
130 It's basically gonna be a trade off.
131
132 =cut
133