Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 397 lines (295 sloc) 15.493 kb
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
1 NAME
2 Class::InsideOut - a safe, simple inside-out object construction kit
6913810 David Golden r3884@vesta (orig r410): david | 2006-06-09 02:46:58 -0400
authored
3
7a92370 David Golden r4161@vesta (orig r670): dagolden | 2006-07-27 12:32:25 -0400
authored
4 VERSION
253e6e8 David Golden bump version to 1.10
authored
5 This documentation refers to version 1.10
7a92370 David Golden r4161@vesta (orig r670): dagolden | 2006-07-27 12:32:25 -0400
authored
6
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
7 SYNOPSIS
8 package My::Class;
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
9
10 use Class::InsideOut qw( public readonly private register id );
11
12 public name => my %name; # accessor: name()
e7aa6f9 David Golden bump version to 1.05
authored
13 readonly ssn => my %ssn; # read-only accessor: ssn()
14 private age => my %age; # no accessor
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
15
16 sub new { register( shift ) }
17
18 sub greeting {
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
19 my $self = shift;
20 return "Hello, my name is $name{ id $self }";
21 }
6913810 David Golden r3884@vesta (orig r410): david | 2006-06-09 02:46:58 -0400
authored
22
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
23 DESCRIPTION
24 This is a simple, safe and streamlined toolkit for building inside-out
25 objects. Unlike most other inside-out object building modules already on
26 CPAN, this module aims for minimalism and robustness:
72c5338 David Golden r3917@vesta (orig r443): david | 2006-06-09 02:56:44 -0400
authored
27
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
28 * Does not require derived classes to subclass it
af0842a David Golden r3947@vesta (orig r473): david | 2006-06-09 03:08:51 -0400
authored
29
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
30 * Uses no source filters, attributes or "CHECK" blocks
4a0b94e David Golden r3962@vesta (orig r488): david | 2006-06-09 03:14:29 -0400
authored
31
7a92370 David Golden r4161@vesta (orig r670): dagolden | 2006-07-27 12:32:25 -0400
authored
32 * Supports any underlying object type including black-box inheritance
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
33
34 * Does not leak memory on object destruction
35
36 * Overloading-safe
37
c9df442 David Golden - STORABLE_attach warns instead of dying if it can't provide a singleton
authored
38 * Thread-safe for Perl 5.8.5 or better
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
39
40 * "mod_perl" compatible
41
42 * Makes no assumption about inheritance or initializer needs
43
44 It provides the minimal support necessary for creating safe inside-out
45 objects and generating flexible accessors.
46
47 Additional documentation
48 * Class::InsideOut::Manual::About -- Guide to the inside-out
49 technique, the "Class::InsideOut" philosophy, and other inside-out
50 implementations
51
52 * Class::InsideOut::Manual::Advanced -- Advanced topics including
7a92370 David Golden r4161@vesta (orig r670): dagolden | 2006-07-27 12:32:25 -0400
authored
53 customizing accessors, black-box inheritance, serialization and
54 thread safety
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
55
56 USAGE
57 Importing "Class::InsideOut"
58 "Class::InsideOut" automatically imports several critical methods into
59 the calling package, including "DESTROY" and support methods for
60 serializing objects with "Storable". These methods are intimately tied
61 to correct functioning of inside-out objects and will always be imported
62 regardless of whether additional functions are requested.
63
64 Additional functions may be imported as usual by including them as
65 arguments to "use". For example:
66
67 use Class::InsideOut qw( register public );
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
68
69 public name => my %name;
70
71 sub new { register( shift ) }
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
72
73 As a shortcut, "Class::InsideOut" supports two tags for importing sets
74 of functions:
75
e7aa6f9 David Golden bump version to 1.05
authored
76 * ":std" provides "id", "private", "public", "readonly" and "register"
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
77
7a92370 David Golden r4161@vesta (orig r670): dagolden | 2006-07-27 12:32:25 -0400
authored
78 * ":all" imports all functions (including an optional constructor)
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
79
80 Note: Automatic imports can be bypassed via "require" or by passing an
81 empty list to "use Class::InsideOut". There is almost no circumstance in
82 which this is a good idea.
83
84 Object properties and accessors
e7aa6f9 David Golden bump version to 1.05
authored
85 Object properties are declared with the "public", "readonly" and
86 "private" functions. They must be passed a label and the lexical hash
87 that will be used to store object properties:
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
88
e7aa6f9 David Golden bump version to 1.05
authored
89 public name => my %name;
90 readonly ssn => my %ssn;
91 private age => my %age;
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
92
93 Properties for an object are accessed through an index into the lexical
94 hash based on the memory address of the object. This memory address
95 *must* be obtained via "Scalar::Util::refaddr". The alias "id" may be
96 imported for brevity.
97
98 $name{ refaddr $self } = "James";
e7aa6f9 David Golden bump version to 1.05
authored
99 $ssn { id $self } = 123456789;
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
100 $age { id $self } = 32;
101
102 Tip: since "refaddr" and "id" are function calls, it may be efficient to
103 store the value once at the beginning of a method, particularly if it is
104 being called repeatedly, e.g. within a loop.
105
106 Object properties declared with "public" will have an accessor created
107 with the same name as the label. If the accessor is passed an argument,
108 the property will be set to the argument. The accessor always returns
109 the value of the property.
110
111 # Outside the class
112 $person = My::Class->new;
113 $person->name( "Larry" );
114
e7aa6f9 David Golden bump version to 1.05
authored
115 Object properties declared with "readonly" will have a read-only
116 accessor created. The accessor will die if passed an argument to set the
117 property value. The property may be set directly in the hash from within
118 the class package as usual.
119
120 # Inside the class
121 $ssn { id $person } = 987654321;
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
122
123 # Inside or outside the class
e7aa6f9 David Golden bump version to 1.05
authored
124 $person->ssn( 123456789 ); # dies
125
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
126 Property accessors may also be hand-written by declaring the property
127 "private" and writing whatever style of accessor is desired. For
128 example:
129
130 sub age { $age{ id $_[0] } }
131 sub set_age { $age{ id $_[0] } = $_[1] }
132
133 Hand-written accessors will be very slightly faster as generated
134 accessors hold a reference to the property hash rather than accessing
135 the property hash directly.
136
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
137 It is also possible to use a package hash instead of a lexical hash to
138 store object properties:
139
140 public name => our %name;
141
142 However, this makes private object data accessable outside the class and
143 incurs a slight performance penalty when accessing the property hash
144 directly; it is not recommended to do this unless you really need it for
145 some specialized reason.
146
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
147 Object construction
148 "Class::InsideOut" provides no default constructor method as there are
149 many possible ways of constructing an inside-out object. This avoids
150 constraining users to any particular object initialization or superclass
151 initialization methodology.
152
153 By using the memory address of the object as the index for properties,
154 *any* type of reference may be used as the basis for an inside-out
155 object with "Class::InsideOut".
156
157 sub new {
158 my $class = shift;
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
159
160 my $self = \( my $scalar ); # anonymous scalar
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
161 # my $self = {}; # anonymous hash
162 # my $self = []; # anonymous array
163 # open my $self, "<", $filename; # filehandle reference
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
164
165 bless $self, $class;
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
166 register( $self );
167 }
168
169 However, to ensure that the inside-out object is thread-safe, the
170 "register" function *must* be called on the newly created object. The
171 "register" function may also be called with just the class name for the
172 common case of blessing an anonymous scalar.
173
174 register( $class ); # same as register( bless \(my $s), $class )
175
176 As a convenience, "Class::InsideOut" provides an optional "new"
e7aa6f9 David Golden bump version to 1.05
authored
177 constructor for simple objects. This constructor automatically
178 initializes the object from key/value pairs passed to the constructor
179 for all keys matching the name of a property (including otherwise
180 "private" or "readonly" properties).
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
181
182 A more advanced technique for object construction uses another object,
7a92370 David Golden r4161@vesta (orig r670): dagolden | 2006-07-27 12:32:25 -0400
authored
183 usually a superclass object, as the object reference. See "black-box
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
184 inheritance" in Class::InsideOut::Manual::Advanced.
185
186 Object destruction
187 "Class::InsideOut" automatically exports a special "DESTROY" function.
188 This function cleans up object property memory for all declared
189 properties the class and for all "Class::InsideOut" based classes in the
190 @ISA array to avoid memory leaks or data collision.
191
192 Additionally, if a user-supplied "DEMOLISH" function is available in the
193 same package, it will be called with the object being destroyed as its
194 argument. "DEMOLISH" can be used for custom destruction behavior such as
195 updating class properties, closing sockets or closing database
196 connections. Object properties will not be deleted until after
197 "DEMOLISH" returns.
198
199 # Sample DEMOLISH: Count objects demolished (for whatever reason)
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
200
201 my $objects_destroyed;
202
203 sub DEMOLISH {
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
204 $objects_destroyed++;
205 }
206
207 "DEMOLISH" will only be called if it exists for an object's actual
208 class. "DEMOLISH" will not be inherited and "DEMOLISH" will not be
209 called automatically for any superclasses.
210
211 "DEMOLISH" should manage any necessary calls to superclass "DEMOLISH"
212 methods. As with "new", implementation details are left to the user
213 based on the user's approach to object inheritance. Depending on how the
214 inheritance chain is constructed and how "DEMOLISH" is being used, users
215 may wish to entirely override superclass "DEMOLISH" methods, rely upon
216 "SUPER::DEMOLISH", or may prefer to walk the entire @ISA tree:
217
218 use Class::ISA;
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
219
220 sub DEMOLISH {
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
221 my $self = shift;
222 # class specific demolish actions
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
223
224 # DEMOLISH for all parent classes, but only once
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
225 my @parents = Class::ISA::super_path( __PACKAGE__ );
226 my %called;
227 for my $p ( @parents ) {
228 my $demolish = $p->can('DEMOLISH');
229 $demolish->($self) if not $called{ $demolish }++;
230 }
231 }
232
233 FUNCTIONS
234 "id"
235 $name{ id $object } = "Larry";
236
237 This is a shorter, mnemonic alias for "Scalar::Util::refaddr". It
238 returns the memory address of an object (just like "refaddr") as the
239 index to access the properties of an inside-out object.
240
241 "new"
242 My::Class->new( name => "Larry", age => 42 );
243
244 This simplistic constructor is provided as a convenience and is only
245 exported on request. When called as a class method, it returns a blessed
246 anonymous scalar. Arguments will be used to initialize all matching
7a92370 David Golden r4161@vesta (orig r670): dagolden | 2006-07-27 12:32:25 -0400
authored
247 inside-out class properties in the @ISA tree. The argument may be a hash
248 or hash reference.
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
249
2d3038b David Golden update Changes and meta for 1.10 release
authored
250 Note: Properties are set directly, not via accessors. This means
251 "set_hook" functions will not be called. For more robust argument
252 checking, you will need to implement your own constructor.
253
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
254 "options"
255 Class::InsideOut::options( \%new_options );
256 %current_options = Class::InsideOut::options();
257
258 The "options" function sets default options for use with all subsquent
259 property definitions for the calling package. If called without
260 arguments, this function will return the options currently in effect.
261 When called with a hash reference of options, these will be joined with
262 the existing defaults, overriding any options of the same name.
263
264 "private"
265 private weight => my %weight;
266 private haircolor => my %hair_color, { %options };
267
268 This is an alias to "property" that also sets the privacy option to
269 'private'. It will override default options or options passed as an
270 argument.
271
272 "property"
273 property name => my %name;
274 property rank => my %rank, { %options };
275
276 Declares an inside-out property. Two arguments are required and a third
277 is optional. The first is a label for the property; this label will be
278 used for introspection and generating accessors and thus must be a valid
279 perl identifier. The second argument must be the lexical hash that will
280 be used to store data for that property. Note that the "my" keyword can
281 be included as part of the argument rather than as a separate statement.
282 The property will be tracked for memory cleanup during object
283 destruction and for proper thread-safety.
284
285 If a third, optional argument is provided, it must be a reference to a
286 hash of options that will be applied to the property and will override
287 any default options that have been set.
288
289 "public"
290 public height => my %height;
291 public age => my %age, { %options };
292
293 This is an alias to "property" that also sets the privacy option to
294 'public'. It will override default options or options passed as an
295 argument.
296
e7aa6f9 David Golden bump version to 1.05
authored
297 "readonly"
298 readonly ssn => my %ssn;
299 readonly fingerprint => my %fingerprint, { %options };
300
301 This is an alias to "property" that sets the privacy option to 'public'
302 and adds a "set_hook" option that dies if an attempt is made to use the
303 accessor to change the property. It will override default options or
304 options passed as an argument.
305
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
306 "register"
307 register( bless( $object, $class ) ); # register the object
308 register( $reference, $class ); # automatic bless
309 register( $class ); # automatic blessed scalar
310
311 Registers objects for thread-safety. This should be called as part of a
312 constructor on a object blessed into the current package. Returns the
313 resulting object. When called with only a class name, "register" will
314 bless an anonymous scalar reference into the given class. When called
315 with both a reference and a class name, "register" will bless the
316 reference into the class.
317
318 OPTIONS
319 Options customize how properties are generated. Options may be set as a
320 default with the "options" function or passed as a hash reference to
321 "public", "private" or "property".
322
323 Valid options include:
324
325 "privacy"
326 property rank => my %rank, { privacy => 'public' };
327 property serial => my %serial, { privacy => 'private' };
328
329 If the *privacy* option is set to *public*, an accessor will be created
330 with the same name as the label. If the accessor is passed an argument,
331 the property will be set to the argument. The accessor always returns
332 the value of the property.
333
334 "get_hook"
335 public list => my %list, {
336 get_hook => sub { @$_ }
337 };
338
339 Defines an accessor hook for when values are retrieved. $_ is locally
340 aliased to the property value for the object. *The return value of the
341 hook is passed through as the return value of the accessor.* See
342 "Customizing Accessors" in Class::InsideOut::Manual::Advanced for
343 details.
344
345 "set_hook"
346 public age => my %age, {
347 set_hook => sub { /^\d+$/ or die "must be an integer" }
348 };
349
350 Defines an accessor hook for when values are set. The hook subroutine
351 receives the entire argument list. $_ is locally aliased to the first
352 argument for convenience. The property receives the value of $_. See
353 "Customizing Accessors" in Class::InsideOut::Manual::Advanced for
354 details.
355
356 SEE ALSO
357 Programmers seeking a more full-featured approach to inside-out objects
358 are encouraged to explore Object::InsideOut. Other implementations are
359 also noted in Class::InsideOut::Manual::About.
360
57ab0ef David Golden - bugfix: allow use of upper or mixed case property accessors
authored
361 KNOWN LIMITATIONS
362 Requires weak reference support (Perl >= 5.6) and Scalar::Util::weaken()
363 to avoid memory leaks and to provide thread-safety.
364
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
365 ROADMAP
366 Features slated for after the 1.0 release include:
367
368 * Adding support for Data::Dump::Streamer serialization hooks
369
370 * Adding additional accessor styles (e.g. get_name()/set_name())
371
372 * Further documentation revisions and clarification
373
374 BUGS
6012750 David Golden - bumped version to 1.0301; removed email bug report notice
authored
375 Please report bugs or feature requests using the CPAN Request Tracker:
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
376 <http://rt.cpan.org/Public/Dist/Display.html?Name=Class-InsideOut>
377
378 When submitting a bug or request, please include a test-file or a patch
379 to an existing test-file that illustrates the bug or desired feature.
380
381 AUTHOR
382 David A. Golden (DAGOLDEN)
383
384 COPYRIGHT AND LICENSE
e7aa6f9 David Golden bump version to 1.05
authored
385 Copyright (c) 2006, 2007 by David A. Golden
7acd3aa David Golden r4157@vesta (orig r666): dagolden | 2006-07-27 11:36:24 -0400
authored
386
63f065c David Golden - Changed to Apache License
authored
387 Licensed under the Apache License, Version 2.0 (the "License"); you may
388 not use this file except in compliance with the License. You may obtain
389 a copy of the License at L<http://www.apache.org/licenses/LICENSE-2.0>
390
391 Unless required by applicable law or agreed to in writing, software
392 distributed under the License is distributed on an "AS IS" BASIS,
393 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
394 See the License for the specific language governing permissions and
395 limitations under the License.
93cc423 David Golden r3938@vesta (orig r464): david | 2006-06-09 03:04:30 -0400
authored
396
Something went wrong with that request. Please try again.