Commit | Line | Data |
d90b42a6 |
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 | |