1Object::InsideOut(3) User Contributed Perl Documentation Object::InsideOut(3)
2
3
4
6 Object::InsideOut - Comprehensive inside-out object support module
7
9 This document describes Object::InsideOut version 2.06
10
12 package My::Class; {
13 use Object::InsideOut;
14
15 # Numeric field
16 # With combined get+set accessor
17 my @data
18 :Field
19 :Type(Numeric)
20 :Accessor(data);
21
22 # Takes 'INPUT' (or 'input', etc.) as a mandatory parameter to ->new()
23 my %init_args :InitArgs = (
24 'INPUT' => {
25 'Regex' => qr/^input$/i,
26 'Mandatory' => 1,
27 'Type' => 'NUMERIC',
28 },
29 );
30
31 # Handle class-specific args as part of ->new()
32 sub init :Init
33 {
34 my ($self, $args) = @_;
35
36 # Put 'input' parameter into 'data' field
37 $self->set(\@data, $args->{'INPUT'});
38 }
39 }
40
41 package My::Class::Sub; {
42 use Object::InsideOut qw(My::Class);
43
44 # List field
45 # With standard 'get_X' and 'set_X' accessors
46 # Takes 'INFO' as an optional list parameter to ->new()
47 # Value automatically added to @info array
48 # Defaults to [ 'empty' ]
49 my @info
50 :Field
51 :Type(List)
52 :Standard(info)
53 :Arg('Name' => 'INFO', 'Default' => 'empty');
54 }
55
56 package Foo; {
57 use Object::InsideOut;
58
59 # Field containing My::Class objects
60 # With combined accessor
61 # Plus automatic parameter processing on object creation
62 my @foo
63 :Field
64 :Type(My::Class)
65 :All(foo);
66 }
67
68 package main;
69
70 my $obj = My::Class::Sub->new('Input' => 69);
71 my $info = $obj->get_info(); # [ 'empty' ]
72 my $data = $obj->data(); # 69
73 $obj->data(42);
74 $data = $obj->data(); # 42
75
76 $obj = My::Class::Sub->new('INFO' => 'help', 'INPUT' => 86);
77 $data = $obj->data(); # 86
78 $info = $obj->get_info(); # [ 'help' ]
79 $obj->set_info(qw(foo bar baz));
80 $info = $obj->get_info(); # [ 'foo', 'bar', 'baz' ]
81
82 my $foo_obj = Foo->new('foo' => $obj);
83 $foo_obj->foo()->data(); # 86
84
86 This module provides comprehensive support for implementing classes
87 using the inside-out object model.
88
89 Object::InsideOut implements inside-out objects as anonymous scalar
90 references that are blessed into a class with the scalar containing the
91 ID for the object (usually a sequence number). For Perl 5.8.3 and
92 later, the scalar reference is set as read-only to prevent accidental
93 modifications to the ID. Object data (i.e., fields) are stored within
94 the class's package in either arrays indexed by the object's ID, or
95 hashes keyed to the object's ID.
96
97 The virtues of the inside-out object model over the blessed hash object
98 model have been extolled in detail elsewhere. See the informational
99 links under "SEE ALSO". Briefly, inside-out objects offer the follow‐
100 ing advantages over blessed hash objects:
101
102 * Encapsulation
103 Object data is enclosed within the class's code and is accessible
104 only through the class-defined interface.
105
106 * Field Name Collision Avoidance
107 Inheritance using blessed hash classes can lead to conflicts if any
108 classes use the same name for a field (i.e., hash key). Inside-out
109 objects are immune to this problem because object data is stored
110 inside each class's package, and not in the object itself.
111
112 * Compile-time Name Checking
113 A common error with blessed hash classes is the misspelling of
114 field names:
115
116 $obj->{'coment'} = 'Say what?'; # Should be 'comment' not 'coment'
117
118 As there is no compile-time checking on hash keys, such errors do
119 not usually manifest themselves until runtime.
120
121 With inside-out objects, text hash keys are not used for accessing
122 field data. Field names and the data index (i.e., $$self) are
123 checked by the Perl compiler such that any typos are easily caught
124 using "perl -c".
125
126 $coment[$$self] = $value; # Causes a compile-time error
127 # or with hash-based fields
128 $comment{$$slef} = $value; # Also causes a compile-time error
129
130 Object::InsideOut offers all the capabilities of other inside-out
131 object modules with the following additional key advantages:
132
133 * Speed
134 When using arrays to store object data, Object::InsideOut objects
135 are as much as 40% faster than blessed hash objects for fetching
136 and setting data, and even with hashes they are still several per‐
137 cent faster than blessed hash objects.
138
139 * Threads
140 Object::InsideOut is thread safe, and thoroughly supports sharing
141 objects between threads using threads::shared.
142
143 * Flexibility
144 Allows control over object ID specification, accessor naming,
145 parameter name matching, and much more.
146
147 * Runtime Support
148 Supports classes that may be loaded at runtime (i.e., using
149 "eval { require ...; };"). This makes it usable from within
150 mod_perl, as well. Also supports dynamic creation of object fields
151 during runtime.
152
153 * Perl 5.6 and 5.8
154 Tested on Perl v5.6.0 through v5.6.2, v5.8.0 through v5.8.8, and
155 v5.9.4.
156
157 * Exception Objects
158 Object::InsideOut uses Exception::Class for handling errors in an
159 OO-compatible manner.
160
161 * Object Serialization
162 Object::InsideOut has built-in support for object dumping and
163 reloading that can be accomplished in either an automated fashion
164 or through the use of class-supplied subroutines. Serialization
165 using Storable is also supported.
166
167 * Foreign Class Inheritance
168 Object::InsideOut allows classes to inherit from foreign (i.e.,
169 non-Object::InsideOut) classes, thus allowing you to sub-class
170 other Perl class, and access their methods from your own objects.
171
172 * Introspection
173 Obtain constructor parameters and method metadata for
174 Object::InsideOut classes.
175
177 To use this module, each of your classes will start with
178 "use Object::InsideOut;":
179
180 package My::Class; {
181 use Object::InsideOut;
182 ...
183 }
184
185 Sub-classes (child classes) inherit from base classes (parent classes)
186 by telling Object::InsideOut what the parent class is:
187
188 package My::Sub; {
189 use Object::InsideOut qw(My::Parent);
190 ...
191 }
192
193 Multiple inheritance is also supported:
194
195 package My::Project; {
196 use Object::InsideOut qw(My::Class Another::Class);
197 ...
198 }
199
200 Object::InsideOut acts as a replacement for the "base" pragma: It
201 loads the parent module(s), calls their "import" functions, and sets up
202 the sub-class's @ISA array. Therefore, you should not "use base ..."
203 yourself, nor try to set up @ISA arrays. Further, you should not use a
204 class's @ISA array to determine a class's hierarchy: See "INTROSPEC‐
205 TION" for details on how to do this.
206
207 If a parent class takes parameters (e.g., symbols to be exported via
208 Exporter), enclose them in an array ref (mandatory) following the name
209 of the parent class:
210
211 package My::Project; {
212 use Object::InsideOut 'My::Class' => [ 'param1', 'param2' ],
213 'Another::Class' => [ 'param' ];
214 ...
215 }
216
218 Object Creation
219
220 Objects are created using the "->new()" method which is exported by
221 Object::InsideOut to each class, and is invoked in the following man‐
222 ner:
223
224 my $obj = My::Class->new();
225
226 Object::InsideOut then handles all the messy details of initializing
227 the object in each of the classes in the invoking class's hierarchy.
228 As such, classes do not (normally) implement their own "->new()"
229 method.
230
231 Usually, object fields are initially populated with data as part of the
232 object creation process by passing parameters to the "->new()" method.
233 Parameters are passed in as combinations of "key => value" pairs and/or
234 hash refs:
235
236 my $obj = My::Class->new('param1' => 'value1');
237 # or
238 my $obj = My::Class->new({'param1' => 'value1'});
239 # or even
240 my $obj = My::Class->new(
241 'param_X' => 'value_X',
242 'param_Y' => 'value_Y',
243 {
244 'param_A' => 'value_A',
245 'param_B' => 'value_B',
246 },
247 {
248 'param_Q' => 'value_Q',
249 },
250 );
251
252 Additionally, parameters can be segregated in hash refs for specific
253 classes:
254
255 my $obj = My::Class->new(
256 'foo' => 'bar',
257 'My::Class' => { 'param' => 'value' },
258 'Parent::Class' => { 'data' => 'info' },
259 );
260
261 The initialization methods for both classes in the above will get
262 'foo' => 'bar', "My::Class" will also get 'param' => 'value', and "Par‐
263 ent::Class" will also get 'data' => 'info'. In this scheme, class-spe‐
264 cific parameters will override general parameters specified at a higher
265 level:
266
267 my $obj = My::Class->new(
268 'default' => 'bar',
269 'Parent::Class' => { 'default' => 'baz' },
270 );
271
272 "My::Class" will get 'default' => 'bar', and "Parent::Class" will get
273 'default' => 'baz'.
274
275 Calling "->new()" on an object works, too, and operates the same as
276 calling "->new()" for the class of the object (i.e., "$obj->new()" is
277 the same as "ref($obj)->new()").
278
279 How the parameters passed to the "->new()" method are used to initial‐
280 ize the object is discussed later under "OBJECT INITIALIZATION".
281
282 NOTE: You cannot create objects from Object::InsideOut itself:
283
284 # This is an error
285 # my $obj = Object::InsideOut->new();
286
287 In this way, Object::InsideOut is not an object class, but functions
288 more like a pragma.
289
290 Object IDs
291
292 As stated earlier, this module implements inside-out objects as anony‐
293 mous, read-only scalar references that are blessed into a class with
294 the scalar containing the ID for the object.
295
296 Within methods, the object is passed in as the first argument:
297
298 sub my_method
299 {
300 my $self = shift;
301 ...
302 }
303
304 The object's ID is then obtained by dereferencing the object: $$self.
305 Normally, this is only needed when accessing the object's field data:
306
307 my @my_field :Field;
308
309 sub my_method
310 {
311 my $self = shift;
312 ...
313 my $data = $my_field[$$self];
314 ...
315 }
316
317 At all other times, and especially in application code, the object
318 should be treated as an opaque entity.
319
321 Much of the power of Object::InsideOut comes from the use of
322 attributes: Tags on variables and subroutines that the attributes mod‐
323 ule sends to Object::InsideOut at compile time. Object::InsideOut then
324 makes use of the information in these tags to handle such operations as
325 object construction, automatic accessor generation, and so on.
326
327 (Note: The use of attibutes is not the same thing as source filter‐
328 ing.)
329
330 An attribute consists of an identifier preceeded by a colon, and
331 optionally followed by a set of parameters in parentheses. For exam‐
332 ple, the attributes on the following array declare it as an object
333 field, and specify the generation of an accessor method for that field:
334
335 my @level :Field :Accessor(level);
336
337 When multiple attributes are assigned to a single entity, they may all
338 appear on the same line (as shown above), or on separate lines:
339
340 my @level
341 :Field
342 :Accessor(level);
343
344 However, due to limitations in the Perl parser, the entirety of any one
345 attribute must be on a single line:
346
347 # This doesn't work
348 # my @level
349 # :Field
350 # :Accessor('Name' => 'level',
351 # 'Return' => 'Old');
352
353 # Each attribute must be all on one line
354 my @level
355 :Field
356 :Accessor('Name' => 'level', 'Return' => 'Old');
357
358 For Object::InsideOut's purposes, the case of an attribute's name does
359 not matter:
360
361 my @data :Field;
362 # or
363 my @data :FIELD;
364
365 However, by convention (as denoted in the attributes module), an
366 attribute's name should not be all lowercase.
367
369 Field Declarations
370
371 Object data fields consist of arrays within a class's package into
372 which data are stored using the object's ID as the array index. An
373 array is declared as being an object field by following its declaration
374 with the ":Field" attribute:
375
376 my @info :Field;
377
378 Object data fields may also be hashes:
379
380 my %data :Field;
381
382 However, as array access is as much as 40% faster than hash access, you
383 should stick to using arrays. See "HASH ONLY CLASSES" for more infor‐
384 mation on when hashes may be required.
385
386 Getting Data
387
388 In class code, data can be fetched directly from an object's field
389 array (hash) using the object's ID:
390
391 $data = $field[$$self];
392 # or
393 $data = $field{$$self};
394
395 Setting Data
396
397 Analogous to the above, data can be put directly into an object's field
398 array (hash) using the object's ID:
399
400 $field[$$self] = $data;
401 # or
402 $field{$$self} = $data;
403
404 However, in threaded applications that use data sharing (i.e., use
405 "threads::shared"), the above will not work when the object is shared
406 between threads and the data being stored is either an array, hash or
407 scalar reference (this includes other objects). This is because the
408 $data must first be converted into shared data before it can be put
409 into the field.
410
411 Therefore, Object::InsideOut automatically exports a method called
412 "->set()" to each class. This method should be used in class code to
413 put data into object fields whenever there is the possibility that the
414 class code may be used in an application that uses threads::shared
415 (i.e., to make your class code thread-safe). The "->set()" method han‐
416 dles all details of converting the data to a shared form, and storing
417 it in the field.
418
419 The "->set()" method, requires two arguments: A reference to the
420 object field array/hash, and the data (as a scalar) to be put in it:
421
422 my @my_field :Field;
423
424 sub store_data
425 {
426 my ($self, $data) = @_;
427 ...
428 $self->set(\@my_field, $data);
429 }
430
431 To be clear, the "->set()" method is used inside class code; not appli‐
432 cation code. Use it inside any object methods that set data in object
433 field arrays/hashes.
434
435 In the event of a method naming conflict, the "->set()" method can be
436 called using its fully-qualified name:
437
438 $self->Object::InsideOut::set(\@field, $data);
439
441 As stated in "Object Creation", object fields are initially populated
442 with data as part of the object creation process by passing
443 "key => value" parameters to the "->new()" method. These parameters
444 can be processed automatically into object fields, or can be passed to
445 a class-specific object initialization subroutine.
446
447 Field-Specific Parameters
448
449 When an object creation parameter corresponds directly to an object
450 field, you can specify for Object::InsideOut to automatically place the
451 parameter into the field by adding the ":Arg" attribute to the field
452 declaration:
453
454 my @foo :Field :Arg(foo);
455
456 For the above, the following would result in $val being placed in
457 "My::Class"'s @foo field during object creation:
458
459 my $obj = My::Class->new('foo' => $val);
460
461 Object Initialization Subroutines
462
463 Many times, object initialization parameters do not correspond directly
464 to object fields, or they may require special handling. For these,
465 parameter processing is accomplished through a combination of an ":Ini‐
466 tArgs" labeled hash, and an ":Init" labeled subroutine.
467
468 The ":InitArgs" labeled hash specifies the parameters to be extracted
469 from the argument list supplied to the "->new()" method. Those parame‐
470 ters (and only those parameters) which match the keys in the ":Ini‐
471 tArgs" hash are then packaged together into a single hash ref. The
472 newly created object and this parameter hash ref are then sent to the
473 ":Init" subroutine for processing.
474
475 Here is an example of a class with an automatically handled field and
476 an :Init handled field:
477
478 package My::Class; {
479 use Object::InsideOut;
480
481 # Automatically handled field
482 my @my_data :Field :Acc(data) :Arg(MY_DATA);
483
484 # ':Init' handled field
485 my @my_field :Field;
486
487 my %init_args :InitArgs = (
488 'MY_PARAM' => '',
489 );
490
491 sub _init :Init
492 {
493 my ($self, $args) = @_;
494
495 if (exists($args->{'MY_PARAM'})) {
496 $self->set(\@my_field, $args->{'MY_PARAM'});
497 }
498 }
499
500 ...
501 }
502
503 An object for this class would be created as follows:
504
505 my $obj = My::Class->new('MY_DATA' => $dat,
506 'MY_PARAM' => $parm);
507
508 This results in, first of all, $dat being placed in the object's
509 @my_data field because the "MY_DATA" key is specified in the ":Arg"
510 attribute for that field.
511
512 Then, "_init" is invoked with arguments consisting of the object (i.e.,
513 $self) and a hash ref consisting only of "{ 'MY_PARAM' => $param }"
514 because the key "MY_PARAM" is specified in the ":InitArgs" hash.
515 "_init" checks that the parameter "MY_PARAM" exists in the hash ref,
516 and then (since it does exist) adds $parm to the object's @my_field
517 field.
518
519 Data processed by the ":Init" subroutine may be placed directly into
520 the class's field arrays (hashes) using the object's ID (i.e., $$self):
521
522 $my_field[$$self] = $args->{'MY_PARAM'};
523
524 However, as shown in the example above, it is strongly recommended that
525 you use the ->set() method:
526
527 $self->set(\@my_field, $args->{'MY_PARAM'});
528
529 which handles converting the data to a shared format when needed for
530 applications using threads::shared.
531
532 Mandatory Parameters
533
534 Field-specific parameters may be declared mandatory as follows:
535
536 my @data :Field
537 :Arg('Name' => 'data', 'Mandatory' => 1);
538
539 If a mandatory parameter is missing from the argument list to
540 "->new()", an error is generated.
541
542 For ":Init" handled parameters, use:
543
544 my %init_args :InitArgs = (
545 'data' => {
546 'Mandatory' => 1,
547 },
548 );
549
550 "Mandatory" may be abbreviated to "Mand", and "Required" or "Req" are
551 synonymous.
552
553 Default Values
554
555 For optional parameters, defaults can be specified for field-specific
556 parameters:
557
558 my @data :Field
559 :Arg('Name' => 'data', 'Default' => 'foo');
560
561 If an optional parameter with a specified default is missing from the
562 argument list to "->new()", then the default is assigned to the field
563 when the object is created.
564
565 The format for ":Init" handled parameters is:
566
567 my %init_args :InitArgs = (
568 'data' => {
569 'Default' => 'foo',
570 },
571 );
572
573 In this case, if the parameter is missing from the argument list to
574 "->new()", then the parameter key is paired with the default value and
575 added to the ":Init" argument hash ref (e.g., "{ 'data' => 'foo' }").
576
577 "Default" may be abbreviated to "Def".
578
579 Parameter Name Matching
580
581 Rather than having to rely on exact matches to parameter keys in the
582 "->new()" argument list, you can specify a regular expressions to be
583 used to match them to field-specific parameters:
584
585 my @param :Field
586 :Arg('Name' => 'param', 'Regexp' => qr/^PARA?M$/i);
587
588 In this case, the parameter's key could be any of the following: PARAM,
589 PARM, Param, Parm, param, parm, and so on. And the following would
590 result in $data being placed in "My::Class"'s @param field during
591 object creation:
592
593 my $obj = My::Class->new('Parm' => $data);
594
595 For ":Init" handled parameters, you would similarly use:
596
597 my %init_args :InitArgs = (
598 'Param' => {
599 'Regex' => qr/^PARA?M$/i,
600 },
601 );
602
603 In this case, the match results in "{ 'Param' => $data }" being sent to
604 the ":Init" subroutine as the argument hash. Note that the ":InitArgs"
605 hash key is substituted for the original argument key. This eliminates
606 the need for any parameter key pattern matching within the ":Init" sub‐
607 routine.
608
609 "Regexp" may be abbreviated to "Regex" or "Re".
610
612 Occassionally, a child class may need to send a parameter to a parent
613 class as part of object initialization. This can be accomplished by
614 supplying a ":PreInit" labeled subroutine in the child class. These
615 subroutines, if found, are called in order from the bottom of the class
616 hierarchy upwards (i.e., child classes first).
617
618 The subroutine should expect two arguments: The newly created (un-ini‐
619 tialized) object (i.e., $self), and a hash ref of all the parameters
620 from the "->new()" method call, including any additional parameters
621 added by other ":PreInit" subroutines. The hash ref will not be
622 exactly as supplied to "->new()", but will be flattened into a single
623 hash ref. For example,
624
625 my $obj = My::Class->new(
626 'param_X' => 'value_X',
627 {
628 'param_A' => 'value_A',
629 'param_B' => 'value_B',
630 },
631 'My::Class' => { 'param' => 'value' },
632 );
633
634 would produce
635
636 {
637 'param_X' => 'value_X',
638 'param_A' => 'value_A',
639 'param_B' => 'value_B',
640 'My::Class' => { 'param' => 'value' }
641 }
642
643 as the hash ref to the ":PreInit" subroutine.
644
645 The ":PreInit" subroutine may then add, modify or even remove any
646 parameters from the hash ref as needed for its purposes.
647
648 After all the ":PreInit" subroutines have been executed, object ini‐
649 tialization will then proceed using the resulting parameter hash.
650
652 Accessors are object methods used to get data out of and put data into
653 an object. You can, of course, write your own accessor code, but this
654 can get a bit tedious, especially if your class has lots of fields.
655 Object::InsideOut provides the capability to automatically generate
656 accessors for you.
657
658 Basic Accessors
659
660 A get accessor is vary basic: It just returns the value of an object's
661 field:
662
663 my @data :Field;
664
665 sub fetch_data
666 {
667 my $self = shift;
668 return ($data[$$self]);
669 }
670
671 and you would use it as follows:
672
673 my $data = $obj->fetch_data();
674
675 To have Object::InsideOut generate such a get accessor for you, add a
676 ":Get" attribute to the field declaration, specifying the name for the
677 accessor in parentheses:
678
679 my @data :Field :Get(fetch_data);
680
681 Similarly, a set accessor puts data in an object's field. The set
682 accessors generated by Object::InsideOut check that they are called
683 with at least one argument. They are specified using the ":Set"
684 attribute:
685
686 my @data :Field :Set(store_data);
687
688 Some programmers use the convention of naming get and set accessors
689 using get_ and set_ prefixes. Such standard accessors can be generated
690 using the ":Standard" attribute (which may be abbreviated to ":Std"):
691
692 my @data :Field :Std(data);
693
694 which is equivalent to:
695
696 my @data :Field :Get(get_data) :Set(set_data);
697
698 Other programmers perfer to use a single combination accessors that
699 performs both functions: When called with no arguments, it gets, and
700 when called with an argument, it sets. Object::InsideOut will generate
701 such accessors with the ":Accessor" attribute. (This can be abbrevi‐
702 ated to ":Acc", or you can use ":Get_Set" or ":Combined" or ":Combo" or
703 even "Mutator".) For example:
704
705 my @data :Field :Acc(data);
706
707 The generated accessor would be used in this manner:
708
709 $obj->data($val); # Puts data into the object's field
710 my $data = $obj->data(); # Fetches the object's field data
711
712 Set Accessor Return Value
713
714 For any of the automatically generated methods that perform set opera‐
715 tions, the default for the method's return value is the value being set
716 (i.e., the new value).
717
718 You can specify the set accessor's return value using the "Return"
719 attribute parameter (which may be abbreviated to "Ret"). For example,
720 to explicitly specify the default behavior use:
721
722 my @data :Field :Set('Name' => 'store_data', 'Return' => 'New');
723
724 You can specify that the accessor should return the old (previous)
725 value (or "undef" if unset):
726
727 my @data :Field :Acc('Name' => 'data', 'Ret' => 'Old');
728
729 You may use <Previous>, "Prev" or "Prior" as synonyms for "Old".
730
731 Finally, you can specify that the accessor should return the object
732 itself:
733
734 my @data :Field :Std('Name' => 'data', 'Ret' => 'Object');
735
736 "Object" may be abbreviated to "Obj", and is also synonymous with
737 "Self".
738
739 Method Chaining
740
741 An obvious case where method chaining can be used is when a field is
742 used to store an object: A method for the stored object can be chained
743 to the get accessor call that retrieves that object:
744
745 $obj->get_stored_object()->stored_object_method()
746
747 Chaining can be done off of set accessors based on their return value
748 (see above). In this example with a set accessor that returns the new
749 value:
750
751 $obj->set_stored_object($stored_obj)->stored_object_method()
752
753 the set_stored_object() call stores the new object, returning it as
754 well, and then the stored_object_method() call is invoked via the
755 stored/returned object. The same would work for set accessors that
756 return the old value, too, but in that case the chained method is
757 invoked via the previously stored (and now returned) object.
758
759 If the Want module (version 0.12 or later) is available, then
760 Object::InsideOut also tries to do the right thing with method chaining
761 for set accessors that don't store/return objects. In this case, the
762 object used to invoke the set accessor will also be used to invoke the
763 chained method (just as though the set accessor were declared with
764 'Return' => 'Object'):
765
766 $obj->set_data('data')->do_something();
767
768 To make use of this feature, just add "use Want;" to the beginning of
769 your application.
770
771 Note, however, that this special handling does not apply to get acces‐
772 sors, nor to combination accessors invoked without an argument (i.e.,
773 when used as a get accessor). These must return objects in order for
774 method chaining to succeed.
775
776 :lvalue Accessors
777
778 As documented in "Lvalue subroutines" in perlsub, an ":lvalue" subrou‐
779 tine returns a modifiable value. This modifiable value can then, for
780 example, be used on the left-hand side (hence "LVALUE") of an assign‐
781 ment statement, or a substitution regular expression.
782
783 For Perl 5.8.0 and later, Object::InsideOut supports the generation of
784 ":lvalue" accessors such that their use in an "LVALUE" context will set
785 the value of the object's field. Just add "'lvalue' => 1" to the set
786 accessor's attribute. ('lvalue' may be abbreviated to 'lv'.)
787
788 Additionally, ":Lvalue" (or its abbreviation ":lv") may be used for a
789 combined get/set :lvalue accessor. In other words, the following are
790 equivalent:
791
792 :Acc('Name' => 'email', 'lvalue' => 1)
793
794 :Lvalue(email)
795
796 Here is a detailed example:
797
798 package Contact; {
799 use Object::InsideOut;
800
801 # Create separate a get accessor and an :lvalue set accessor
802 my @name :Field
803 :Get(name)
804 :Set('Name' => 'set_name', 'lvalue' => 1);
805
806 # Create a standard get_/set_ pair of accessors
807 # The set_ accessor will be an :lvalue accessor
808 my @phone :Field
809 :Std('Name' => 'phone', 'lvalue' => 1);
810
811 # Create a combined get/set :lvalue accessor
812 my @email :Field
813 :Lvalue(email);
814 }
815
816 package main;
817
818 my $obj = Contact->new();
819
820 # Use :lvalue accessors in assignment statements
821 $obj->set_name() = 'Jerry D. Hedden';
822 $obj->set_phone() = '800-555-1212';
823 $obj->email() = 'jdhedden AT cpan DOT org';
824
825 # Use :lvalue accessor in substituion regexp
826 $obj->email() =~ s/ AT (\w+) DOT /\@$1./;
827
828 # Use :lvalue accessor in a 'substr' call
829 substr($obj->set_phone(), 0, 3) = '888';
830
831 print("Contact info:\n");
832 print("\tName: ", $obj->name(), "\n");
833 print("\tPhone: ", $obj->get_phone(), "\n");
834 print("\tEmail: ", $obj->email(), "\n");
835
836 The use of ":lvalue" accessors requires the installation of the Want
837 module (version 0.12 or later) from CPAN. See particularly the section
838 "Lvalue subroutines:" in Want for more information.
839
840 ":lvalue" accessors also work like regular set accessors in being able
841 to accept arguments, return values, and so on:
842
843 my @pri :Field
844 :Lvalue('Name' => 'priority', 'Return' => 'Old');
845 ...
846 my $old_pri = $obj->priority(10);
847
848 ":lvalue" accessors can be used in method chains.
849
850 CAVEATS
851
852 While still classified as experimental, Perl's support for ":lvalue"
853 subroutines has been around since 5.6.0, and a good number of CPAN mod‐
854 ules make use of them.
855
856 By definition, because ":lvalue" accessors return the location of a
857 field, they break encapsulation. As a result, some OO advocates eschew
858 the use of ":lvalue" accessors.
859
860 ":lvalue" accessors are slower than corresponding non-lvalue accessors.
861 This is due to the fact that more code is needed to handle all the
862 diverse ways in which ":lvalue" accessors may be used. (I've done my
863 best to optimize the generated code.) For example, here's the code
864 that is generated for a simple combined accessor:
865
866 *Foo::foo = sub {
867 return ($$field[${$_[0]}]) if (@_ == 1);
868 $$field[${$_[0]}] = $_[1];
869 };
870
871 And the corresponding code for an ":lvalue" combined accessor:
872
873 *Foo::foo = sub :lvalue {
874 my $rv = !Want::want_lvalue(0);
875 Want::rreturn($$field[${$_[0]}]) if ($rv && (@_ == 1));
876 my $assign;
877 if (my @args = Want::wantassign(1)) {
878 @_ = ($_[0], @args);
879 $assign = 1;
880 }
881 if (@_ > 1) {
882 $$field[${$_[0]}] = $_[1];
883 Want::lnoreturn if $assign;
884 Want::rreturn($$field[${$_[0]}]) if $rv;
885 }
886 ((@_ > 1) && (Want::wantref() eq 'OBJECT') &&
887 !Scalar::Util::blessed($$field[${$_[0]}]))
888 ? $_[0] : $$field[${$_[0]}];
889 };
890
892 Parameter naming and accessor generation may be combined:
893
894 my @data :Field :All(data);
895
896 This is syntactic shorthand for:
897
898 my @data :Field :Arg(data) :Acc(data);
899
900 If you want the accessor to be ":lvalue", use:
901
902 my @data :Field :LV_All(data);
903
904 If standard accessors are desired, use:
905
906 my @data :Field :Std_All(data);
907
908 Attribute parameters affecting the set accessor may also be used. For
909 example, if you want standard accessors with an ":lvalue" set accessor:
910
911 my @data :Field :Std_All('Name' => 'data', 'Lvalue' => 1);
912
913 If you want a combined accessor that returns the old value on set oper‐
914 ations:
915
916 my @data :Field :All('Name' => 'data', 'Ret' => 'Old');
917
918 And so on.
919
920 If you need to add attribute parameters that affect the ":Arg" portion
921 (e.g., 'Default', 'Mandatory', etc.), then you cannot use ":All". Fall
922 back to using the separate attributes. For example:
923
924 my @data :Field :Arg('Name' => 'data', 'Mand' => 1)
925 :Acc('Name' => 'data', 'Ret' => 'Old');
926
928 Restricted and Private Methods
929
930 Access to certain methods can be narrowed by use of the ":Restricted"
931 and ":Private" attributes. ":Restricted" methods can only be called
932 from within the class's hierarchy. ":Private" methods can only be
933 called from within the method's class.
934
935 Without the above attributes, most methods have public access. If
936 desired, you may explicitly label them with the ":Public" attribute.
937
938 You can also specify access permissions on automatically generated
939 accessors:
940
941 my @data :Field :Std('Name' => 'data', 'Permission' => 'private');
942 my @info :Field :Set('Name' => 'set_info', 'Perm' => 'restricted');
943 my @internal :Field :Acc('Name' => 'internal', 'Private' => 1);
944 my @state :Field :Get('Name' => 'state', 'Restricted' => 1);
945
946 When creating a standard pair of get_/set_ accessors, the premission
947 setting is applied to both accessors. If different permissions are
948 required on the two accessors, then you'll have to use separate ":Get"
949 and ":Set" attributes on the field.
950
951 # Create a private set method
952 # and a restricted get method on the 'foo' field
953 my @foo :Field
954 :Set('Name' => 'set_foo', 'Priv' => 1);
955 :Get('Name' => 'get_foo', 'Rest' => 1);
956
957 # Create a restricted set method
958 # and a public get method on the 'bar' field
959 my %bar :Field
960 :Set('Name' => 'set_bar', 'Perm' => 'restrict');
961 :Get(get_bar);
962
963 "Permission" may be abbreviated to "Perm"; "Private" may be abbreviated
964 to "Priv"; and "Restricted" may be abbreviated to "Restrict".
965
966 Hidden Methods
967
968 For subroutines marked with the following attributes (most of which are
969 discussed later in this document):
970
971 :ID
972 :PreInit
973 :Init
974 :Replicate
975 :Destroy
976 :Automethod
977 :Dumper
978 :Pumper
979 :MOD_*_ATTRS
980 :FETCH_*_ATTRS
981
982 Object::InsideOut normally renders them uncallable (hidden) to class
983 and application code (as they should normally only be needed by
984 Object::InsideOut itself). If needed, this behavior can be overridden
985 by adding the "Public", "Restricted" or "Private" attribute parameters:
986
987 sub _init :Init(private) # Callable from within this class
988 {
989 my ($self, $args) = @_;
990
991 ...
992 }
993
994 NOTE: A bug in Perl 5.6.0 prevents using these access attribute param‐
995 eters. As such, subroutines marked with the above attributes will be
996 left with public access.
997
998 NOTE: The above cannot be accomplished by using the corresponding per‐
999 mission attributes. For example:
1000
1001 # sub _init :Init :Private # Wrong syntax - doesn't work
1002
1004 Object::InsideOut can be directed to add type-checking code to the
1005 set/combined accessors it generates, and to perform type checking on
1006 object initialization parameters.
1007
1008 Field Type Checking
1009
1010 Type checking for a field can be specified by adding the ":Type"
1011 attribute to the field declaration:
1012
1013 my @data :Field :Type(Numeric);
1014
1015 The ":Type" attribute results in type checking code being added to
1016 set/combined accessors generated by Object::InsideOut, and will perform
1017 type checking on object initialization parameters processed by the
1018 ":Arg" attribute.
1019
1020 Available Types are:
1021
1022 Numeric
1023 Can also be specified as "Num" or "Number". This uses
1024 Scalar::Util::looks_like_number() to test the input value.
1025
1026 List or Array
1027 This type permits an accessor to accept multiple values (which are
1028 then placed in an array ref) or a single array ref.
1029
1030 For object initialization parameters, it permits a single value
1031 (which is then placed in an array ref) or an array ref.
1032
1033 Array_ref
1034 This specifies that only a single array reference is permitted.
1035 Can also be specified as "Arrayref".
1036
1037 Hash
1038 This type permits an accessor to accept multiple "key => value"
1039 pairs (which are then placed in a hash ref) or a single hash ref.
1040
1041 For object initialization parameters, only a single ref is permit‐
1042 ted.
1043
1044 Hash_ref
1045 This specifies that only a single hash reference is permitted. Can
1046 also be specified as "Hashref".
1047
1048 A class name
1049 This permits only an object of the specified class, or one of its
1050 sub-classes (i.e., type checking is done using "->isa()"). For
1051 example, "My::Class".
1052
1053 Other reference type
1054 This permits only a reference of the specified type (as returned by
1055 ref()). The type must be specified in all caps. For example,
1056 "CODE".
1057
1058 The ":Type" attribute can also be supplied with a code reference to
1059 provide custom type checking. The code ref may either be in the form
1060 of an anonymous subroutine, or a fully-qualified subroutine name. The
1061 result of executing the code ref on the input argument should be a
1062 boolean value. Here's some examples:
1063
1064 package My::Class; {
1065 use Object::InsideOut;
1066
1067 # Type checking using an anonymous subroutine
1068 # (This checks that the argument is a scalar)
1069 my @data :Field :Type(sub { ! ref($_[0]) });
1070 :Acc(data)
1071
1072 # Type checking using a fully-qualified subroutine name
1073 my @num :Field :Type(\&My::Class::positive);
1074 :Acc(num)
1075
1076 # The type checking subroutine may be made 'Private'
1077 sub positive :Private
1078 {
1079 return (Scalar::Util::looks_like_number($_[0]) &&
1080 ($_[0] > 0));
1081 }
1082 }
1083
1084 Type Checking on ":Init" Parameters
1085
1086 For object initialization parameters that are sent to the ":Init" sub‐
1087 routine during object initialization, the parameter's type can be spec‐
1088 ified in the ":InitArgs" hash for that parameter using the same types
1089 as specified in the previous section. For example:
1090
1091 my %init_args :InitArgs = (
1092 'DATA' => {
1093 'Type' => 'Numeric',
1094 },
1095 );
1096
1098 Normally, methods with the same name in a class hierarchy are masked
1099 (i.e., overridden) by inheritance - only the method in the most-derived
1100 class is called. With cumulative methods, this masking is removed, and
1101 the same-named method is called in each of the classes within the hier‐
1102 archy. The return results from each call (if any) are then gathered
1103 together into the return value for the original method call. For exam‐
1104 ple,
1105
1106 package My::Class; {
1107 use Object::InsideOut;
1108
1109 sub what_am_i :Cumulative
1110 {
1111 my $self = shift;
1112
1113 my $ima = (ref($self) eq __PACKAGE__)
1114 ? q/I was created as a /
1115 : q/My top class is /;
1116
1117 return ($ima . __PACKAGE__);
1118 }
1119 }
1120
1121 package My::Foo; {
1122 use Object::InsideOut 'My::Class';
1123
1124 sub what_am_i :Cumulative
1125 {
1126 my $self = shift;
1127
1128 my $ima = (ref($self) eq __PACKAGE__)
1129 ? q/I was created as a /
1130 : q/I'm also a /;
1131
1132 return ($ima . __PACKAGE__);
1133 }
1134 }
1135
1136 package My::Child; {
1137 use Object::InsideOut 'My::Foo';
1138
1139 sub what_am_i :Cumulative
1140 {
1141 my $self = shift;
1142
1143 my $ima = (ref($self) eq __PACKAGE__)
1144 ? q/I was created as a /
1145 : q/I'm in class /;
1146
1147 return ($ima . __PACKAGE__);
1148 }
1149 }
1150
1151 package main;
1152
1153 my $obj = My::Child->new();
1154 my @desc = $obj->what_am_i();
1155 print(join("\n", @desc), "\n");
1156
1157 produces:
1158
1159 My top class is My::Class
1160 I'm also a My::Foo
1161 I was created as a My::Child
1162
1163 When called in a list context (as in the above), the return results of
1164 cumulative methods are accumulated, and returned as a list.
1165
1166 In a scalar context, a results object is returned that segregates the
1167 results by class for each of the cumulative method calls. Through
1168 overloading, this object can then be dereferenced as an array, hash,
1169 string, number, or boolean. For example, the above could be rewritten
1170 as:
1171
1172 my $obj = My::Child->new();
1173 my $desc = $obj->what_am_i(); # Results object
1174 print(join("\n", @{$desc}), "\n"); # Dereference as an array
1175
1176 The following uses hash dereferencing:
1177
1178 my $obj = My::Child->new();
1179 my $desc = $obj->what_am_i();
1180 while (my ($class, $value) = each(%{$desc})) {
1181 print("Class $class reports:\n\t$value\n");
1182 }
1183
1184 and produces:
1185
1186 Class My::Class reports:
1187 My top class is My::Class
1188 Class My::Child reports:
1189 I was created as a My::Child
1190 Class My::Foo reports:
1191 I'm also a My::Foo
1192
1193 As illustrated above, cumulative methods are tagged with the ":Cumula‐
1194 tive" attribute (or ":Cumulative(top down)"), and propagate from the
1195 top down through the class hierarchy (i.e., from the parent classes
1196 down through the child classes). If tagged with ":Cumulative(bot‐
1197 tom up)", they will propagated from the object's class upwards through
1198 the parent classes.
1199
1201 In addition to ":Cumulative", Object::InsideOut provides a way of cre‐
1202 ating methods that are chained together so that their return values are
1203 passed as input arguments to other similarly named methods in the same
1204 class hierarchy. In this way, the chained methods act as though they
1205 were piped together.
1206
1207 For example, imagine you had a method called "format_name" that formats
1208 some text for display:
1209
1210 package Subscriber; {
1211 use Object::InsideOut;
1212
1213 sub format_name {
1214 my ($self, $name) = @_;
1215
1216 # Strip leading and trailing whitespace
1217 $name =~ s/^\s+//;
1218 $name =~ s/\s+$//;
1219
1220 return ($name);
1221 }
1222 }
1223
1224 And elsewhere you have a second class that formats the case of names:
1225
1226 package Person; {
1227 use Lingua::EN::NameCase qw(nc);
1228 use Object::InsideOut;
1229
1230 sub format_name
1231 {
1232 my ($self, $name) = @_;
1233
1234 # Attempt to properly case names
1235 return (nc($name));
1236 }
1237 }
1238
1239 And you decide that you'd like to perform some formatting of your own,
1240 and then have all the parent methods apply their own formatting. Nor‐
1241 mally, if you have a single parent class, you'd just call the method
1242 directly with "$self->SUPER::format_name($name)", but if you have more
1243 than one parent class you'd have to explicitly call each method
1244 directly:
1245
1246 package Customer; {
1247 use Object::InsideOut qw(Person Subscriber);
1248
1249 sub format_name
1250 {
1251 my ($self, $name) = @_;
1252
1253 # Compress all whitespace into a single space
1254 $name =~ s/\s+/ /g;
1255
1256 $name = $self->Subscriber::format_name($name);
1257 $name = $self->Person::format_name($name);
1258
1259 return $name;
1260 }
1261 }
1262
1263 With Object::InsideOut, you'd add the ":Chained" attribute to each
1264 class's "format_name" method, and the methods will be chained together
1265 automatically:
1266
1267 package Subscriber; {
1268 use Object::InsideOut;
1269
1270 sub format_name :Chained
1271 {
1272 my ($self, $name) = @_;
1273
1274 # Strip leading and trailing whitespace
1275 $name =~ s/^\s+//;
1276 $name =~ s/\s+$//;
1277
1278 return ($name);
1279 }
1280 }
1281
1282 package Person; {
1283 use Lingua::EN::NameCase qw(nc);
1284 use Object::InsideOut;
1285
1286 sub format_name :Chained
1287 {
1288 my ($self, $name) = @_;
1289
1290 # Attempt to properly case names
1291 return (nc($name));
1292 }
1293 }
1294
1295 package Customer; {
1296 use Object::InsideOut qw(Person Subscriber);
1297
1298 sub format_name :Chained
1299 {
1300 my ($self, $name) = @_;
1301
1302 # Compress all whitespace into a single space
1303 $name =~ s/\s+/ /g;
1304
1305 return ($name);
1306 }
1307 }
1308
1309 So passing in someone's name to "format_name" in "Customer" would cause
1310 leading and trailing whitespace to be removed, then the name to be
1311 properly cased, and finally whitespace to be compressed to a single
1312 space. The resulting $name would be returned to the caller:
1313
1314 my ($name) = $obj->format_name($name_raw);
1315
1316 Unlike ":Cumulative" methods, ":Chained" methods always returns an
1317 array - even if there is only one value returned. Therefore,
1318 ":Chained" methods should always be called in an array context, as
1319 illustrated above.
1320
1321 The default direction is to chain methods from the parent classes at
1322 the top of the class hierarchy down through the child classes. You may
1323 use the attribute ":Chained(top down)" to make this more explicit.
1324
1325 If you label the method with the ":Chained(bottom up)" attribute, then
1326 the chained methods are called starting with the object's class and
1327 working upwards through the parent classes in the class hierarchy, sim‐
1328 ilar to how ":Cumulative(bottom up)" works.
1329
1331 As mentioned under "OBJECT CREATION", the "->new()" method can take
1332 parameters that are passed in as combinations of "key => value" pairs
1333 and/or hash refs:
1334
1335 my $obj = My::Class->new(
1336 'param_X' => 'value_X',
1337 'param_Y' => 'value_Y',
1338 {
1339 'param_A' => 'value_A',
1340 'param_B' => 'value_B',
1341 },
1342 {
1343 'param_Q' => 'value_Q',
1344 },
1345 );
1346
1347 The parameters are merged into a single hash ref before they are pro‐
1348 cessed.
1349
1350 Adding the ":MergeArgs" attribute to your methods gives them a similar
1351 capability. Your method will then get two arguments: The object and a
1352 single hash ref of the merged arguments. For example:
1353
1354 package Foo; {
1355 use Object::InsideOut;
1356
1357 ...
1358
1359 sub my_method :MergeArgs {
1360 my ($self, $args) = @_;
1361
1362 my $param = $args->{'param'};
1363 my $data = $args->{'data'};
1364 my $flag = $args->{'flag'};
1365 ...
1366 }
1367 }
1368
1369 package main;
1370
1371 my $obj = Foo->new(...);
1372
1373 $obj->my_method( { 'data' => 42,
1374 'flag' => 'true' },
1375 'param' => 'foo' );
1376
1378 There are significant issues related to Perl's "AUTOLOAD" mechanism
1379 that cause it to be ill-suited for use in a class hierarchy. Therefore,
1380 Object::InsideOut implements its own ":Automethod" mechanism to over‐
1381 come these problems.
1382
1383 Classes requiring "AUTOLOAD"-type capabilities must provided a subrou‐
1384 tine labeled with the ":Automethod" attribute. The ":Automethod" sub‐
1385 routine will be called with the object and the arguments in the origi‐
1386 nal method call (the same as for "AUTOLOAD"). The ":Automethod" sub‐
1387 routine should return either a subroutine reference that implements the
1388 requested method's functionality, or else just end with "return;" to
1389 indicate that it doesn't know how to handle the request.
1390
1391 Using its own "AUTOLOAD" subroutine (which is exported to every class),
1392 Object::InsideOut walks through the class tree, calling each
1393 ":Automethod" subroutine, as needed, to fulfill an unimplemented method
1394 call.
1395
1396 The name of the method being called is passed as $_ instead of
1397 $AUTOLOAD, and does not have the class name prepended to it. If the
1398 ":Automethod" subroutine also needs to access the $_ from the caller's
1399 scope, it is available as $CALLER::_.
1400
1401 Automethods can also be made to act as "CUMULATIVE METHODS" or "CHAINED
1402 METHODS". In these cases, the ":Automethod" subroutine should return
1403 two values: The subroutine ref to handle the method call, and a string
1404 designating the type of method. The designator has the same form as
1405 the attributes used to designate ":Cumulative" and ":Chained" methods:
1406
1407 ':Cumulative' or ':Cumulative(top down)'
1408 ':Cumulative(bottom up)'
1409 ':Chained' or ':Chained(top down)'
1410 ':Chained(bottom up)'
1411
1412 The following skeletal code illustrates how an ":Automethod" subroutine
1413 could be structured:
1414
1415 sub _automethod :Automethod
1416 {
1417 my $self = shift;
1418 my @args = @_;
1419
1420 my $method_name = $_;
1421
1422 # This class can handle the method directly
1423 if (...) {
1424 my $handler = sub {
1425 my $self = shift;
1426 ...
1427 return ...;
1428 };
1429
1430 ### OPTIONAL ###
1431 # Install the handler so it gets called directly next time
1432 # no strict refs;
1433 # *{__PACKAGE__.'::'.$method_name} = $handler;
1434 ################
1435
1436 return ($handler);
1437 }
1438
1439 # This class can handle the method as part of a chain
1440 if (...) {
1441 my $chained_handler = sub {
1442 my $self = shift;
1443 ...
1444 return ...;
1445 };
1446
1447 return ($chained_handler, ':Chained');
1448 }
1449
1450 # This class cannot handle the method request
1451 return;
1452 }
1453
1454 Note: The OPTIONAL code above for installing the generated handler as a
1455 method should not be used with ":Cumulative" or ":Chained" automethods.
1456
1458 Basic Serialization
1459
1460 my $array_ref = $obj->dump();
1461 my $string = $obj->dump(1);
1462 Object::InsideOut exports a method called "->dump()" to each class
1463 that returns either a Perl or a string representation of the object
1464 that invokes the method.
1465
1466 The Perl representation is returned when "->dump()" is called with‐
1467 out arguments. It consists of an array ref whose first element is
1468 the name of the object's class, and whose second element is a hash
1469 ref containing the object's data. The object data hash ref con‐
1470 tains keys for each of the classes that make up the object's hier‐
1471 archy. The values for those keys are hash refs containing
1472 "key => value" pairs for the object's fields. For example:
1473
1474 [
1475 'My::Class::Sub',
1476 {
1477 'My::Class' => {
1478 'data' => 'value'
1479 },
1480 'My::Class::Sub' => {
1481 'life' => 42
1482 }
1483 }
1484 ]
1485
1486 The name for an object field (data and life in the example above)
1487 can be specified by adding the ":Name" attribute to the field:
1488
1489 my @life :Field :Name(life);
1490
1491 If the ":Name" attribute is not used, then the name for a field
1492 will be either the name associated with an ":All" or ":Arg"
1493 attribute, its get method name, its set method name, or, failing
1494 all that, a string of the form "ARRAY(0x...)" or "HASH(0x...)".
1495
1496 When called with a true argument, "->dump()" returns a string ver‐
1497 sion of the Perl representation using Data::Dumper.
1498
1499 Note that using Data::Dumper directly on an inside-out object will
1500 not produce the desired results (it'll just output the contents of
1501 the scalar ref). Also, if inside-out objects are stored inside
1502 other structures, a dump of those structures will not contain the
1503 contents of the object's fields.
1504
1505 In the event of a method naming conflict, the "->dump()" method can
1506 be called using its fully-qualified name:
1507
1508 my $dump = $obj->Object::InsideOut::dump();
1509
1510 my $obj = Object::InsideOut->pump($data);
1511 "Object::InsideOut->pump()" takes the output from the "->dump()"
1512 method, and returns an object that is created using that data. If
1513 $data is the array ref returned by using "$obj->dump()", then the
1514 data is inserted directly into the corresponding fields for each
1515 class in the object's class hierarchy. If $data is the string
1516 returned by using "$obj->dump(1)", then it is "eval"ed to turn it
1517 into an array ref, and then processed as above.
1518
1519 If any of an object's fields are dumped to field name keys of the
1520 form "ARRAY(0x...)" or "HASH(0x...)" (see above), then the data
1521 will not be reloadable using "Object::InsideOut->pump()". To over‐
1522 come this problem, the class developer must either add ":Name"
1523 attributes to the ":Field" declarations (see above), or provide a
1524 ":Dumper"/":Pumper" pair of subroutines as described below.
1525
1526 ":Dumper" Subroutine Attribute
1527 If a class requires special processing to dump its data, then it
1528 can provide a subroutine labeled with the ":Dumper" attribute.
1529 This subroutine will be sent the object that is being dumped. It
1530 may then return any type of scalar the developer deems appropriate.
1531 Usually, this would be a hash ref containing "key => value" pairs
1532 for the object's fields. For example:
1533
1534 my @data :Field;
1535
1536 sub _dump :Dumper
1537 {
1538 my $obj = $_[0];
1539
1540 my %field_data;
1541 $field_data{'data'} = $data[$$obj];
1542
1543 return (\%field_data);
1544 }
1545
1546 Just be sure not to call your ":Dumper" subroutine "dump" as that
1547 is the name of the dump method exported by Object::InsideOut as
1548 explained above.
1549
1550 ":Pumper" Subroutine Attribute
1551 If a class supplies a ":Dumper" subroutine, it will most likely
1552 need to provide a complementary ":Pumper" labeled subroutine that
1553 will be used as part of creating an object from dumped data using
1554 "Object::InsideOut->pump()". The subroutine will be supplied the
1555 new object that is being created, and whatever scalar was returned
1556 by the ":Dumper" subroutine. The corresponding ":Pumper" for the
1557 example ":Dumper" above would be:
1558
1559 sub _pump :Pumper
1560 {
1561 my ($obj, $field_data) = @_;
1562
1563 $obj->set(\@data, $field_data->{'data'});
1564 }
1565
1566 Storable
1567
1568 Object::InsideOut also supports object serialization using the Storable
1569 module. There are two methods for specifying that a class can be seri‐
1570 alized using Storable. The first method involves adding Storable to
1571 the Object::InsideOut declaration in your package:
1572
1573 package My::Class; {
1574 use Object::InsideOut qw(Storable);
1575 ...
1576 }
1577
1578 and adding "use Storable;" in your application. Then you can use the
1579 "->store()" and "->freeze()" methods to serialize your objects, and the
1580 "retrieve()" and "thaw()" subroutines to deserialize them.
1581
1582 package main;
1583 use Storable;
1584 use My::Class;
1585
1586 my $obj = My::Class->new(...);
1587 $obj->store('/tmp/object.dat');
1588 ...
1589 my $obj2 = retrieve('/tmp/object.dat');
1590
1591 The other method of specifying Storable serialization involves setting
1592 a "::storable" variable inside a "BEGIN" block for the class prior to
1593 its use:
1594
1595 package main;
1596 use Storable;
1597
1598 BEGIN {
1599 $My::Class::storable = 1;
1600 }
1601 use My::Class;
1602
1604 Object::InsideOut provides support for various forms of object coercion
1605 through the overload mechanism. For instance, if you want an object to
1606 be usable directly in a string, you would supply a subroutine in your
1607 class labeled with the ":Stringify" attribute:
1608
1609 sub as_string :Stringify
1610 {
1611 my $self = $_[0];
1612 my $string = ...;
1613 return ($string);
1614 }
1615
1616 Then you could do things like:
1617
1618 print("The object says, '$obj'\n");
1619
1620 For a boolean context, you would supply:
1621
1622 sub as_bool :Boolify
1623 {
1624 my $self = $_[0];
1625 my $true_or_false = ...;
1626 return ($true_or_false);
1627 }
1628
1629 and use it in this manner:
1630
1631 if (! defined($obj)) {
1632 # The object is undefined
1633 ....
1634
1635 } elsif (! $obj) {
1636 # The object returned a false value
1637 ...
1638 }
1639
1640 The following coercion attributes are supported:
1641
1642 :Stringify
1643 :Numerify
1644 :Boolify
1645 :Arrayify
1646 :Hashify
1647 :Globify
1648 :Codify
1649
1650 Coercing an object to a scalar (":Scalarify") is not supported as $$obj
1651 is the ID of the object and cannot be overridden.
1652
1654 Object Cloning
1655
1656 Copies of objects can be created using the "->clone()" method which is
1657 exported by Object::InsideOut to each class:
1658
1659 my $obj2 = $obj->clone();
1660
1661 When called without arguments, "->clone()" creates a shallow copy of
1662 the object, meaning that any complex data structures (i.e., array, hash
1663 or scalar refs) stored in the object will be shared with its clone.
1664
1665 Calling "->clone()" with a true argument:
1666
1667 my $obj2 = $obj->clone(1);
1668
1669 creates a deep copy of the object such that internally held array, hash
1670 or scalar refs are replicated and stored in the newly created clone.
1671
1672 Deep cloning can also be controlled at the field level, and is covered
1673 in the next section.
1674
1675 Note that cloning does not clone internally held objects. For example,
1676 if $foo contains a reference to $bar, a clone of $foo will also contain
1677 a reference to $bar; not a clone of $bar. If such behavior is needed,
1678 it must be provided using a :Replicate subroutine.
1679
1680 Field Cloning
1681
1682 Object cloning can be controlled at the field level such that only
1683 specified fields are deeply copied when "->clone()" is called without
1684 any arguments. This is done by adding the ":Deep" attribute to the
1685 field:
1686
1687 my @data :Field :Deep;
1688
1690 Frequently, it is useful to store weakened references to data or
1691 objects in a field. Such a field can be declared as ":Weak" so that
1692 data (i.e., references) set via Object::InsideOut generated accessors,
1693 parameter processing using ":Arg", the "->set()" method, etc., will
1694 automatically be weakened after being stored in the field array/hash.
1695
1696 my @data :Field :Weak;
1697
1698 NOTE: If data in a weak field is set directly (i.e., the "->set()"
1699 method is not used), then weaken() must be invoked on the stored refer‐
1700 ence afterwards:
1701
1702 $field[$$self] = $data;
1703 Scalar::Util::weaken($field[$$self]);
1704
1705 (This is another reason why the "->set()" method is recommended for
1706 setting field data within class code.)
1707
1709 Normally, object fields are declared as part of the class code. How‐
1710 ever, some classes may need the capability to create object fields on-
1711 the-fly, for example, as part of an ":Automethod". Object::InsideOut
1712 provides a class method for this:
1713
1714 # Dynamically create a hash field with standard accessors
1715 My::Class->create_field('%'.$fld, ":Std($fld)");
1716
1717 The first argument is the class into which the field will be added.
1718 The second argument is a string containing the name of the field pre‐
1719 ceeded by either a "@" or "%" to declare an array field or hash field,
1720 respectively. The remaining string arguments should be attributes
1721 declaring accessors and the like. The ":Field" attribute is assumed,
1722 and does not need to be added to the attribute list. For example:
1723
1724 My::Class->create_field('@data', ":Type(numeric)",
1725 ":Acc(data)");
1726
1727 My::Class->create_field('@obj', ":Type(Some::Class)",
1728 ":Acc(obj)",
1729 ":Weak");
1730
1731 Field creation will fail if you try to create an array field within a
1732 class whose hierarchy has been declared :hash_only.
1733
1734 Here's an example of an ":Automethod" subroutine that uses dynamic
1735 field creation:
1736
1737 package My::Class; {
1738 use Object::InsideOut;
1739
1740 sub _automethod :Automethod
1741 {
1742 my $self = $_[0];
1743 my $class = ref($self) ⎪⎪ $self;
1744 my $method = $_;
1745
1746 # Extract desired field name from get_/set_ method name
1747 my ($fld_name) = $method =~ /^[gs]et_(.*)$/;
1748 if (! $fld_name) {
1749 return; # Not a recognized method
1750 }
1751
1752 # Create the field and its standard accessors
1753 $class->create_field('@'.$fld_name, ":Std($fld_name)");
1754
1755 # Return code ref for newly created accessor
1756 no strict 'refs';
1757 return *{$class.'::'.$method}{'CODE'};
1758 }
1759 }
1760
1762 Parameter Preprocessing
1763
1764 You can specify a code ref (either in the form of an anonymous subrou‐
1765 tine, or a fully-qualified subroutine name) for an object initializa‐
1766 tion parameter that will be called on that parameter prior to taking
1767 any of the other parameter actions described above. Here's an example:
1768
1769 package My::Class; {
1770 use Object::InsideOut;
1771
1772 my @data :Field
1773 :Arg('Name' => 'DATA', 'Preprocess' => \&My::Class::preproc);
1774
1775 my %init_args :InitArgs = (
1776 'PARAM' => {
1777 'Preprocess' => \&My::Class::preproc);
1778 },
1779 );
1780
1781 # The parameter preprocessing subroutine may be made 'Private'
1782 sub preproc :Private
1783 {
1784 my ($class, $param, $spec, $obj, $value) = @_;
1785
1786 # Preform parameter preprocessing
1787 ...
1788
1789 # Return result
1790 return ...;
1791 }
1792 }
1793
1794 As the above illustrates, the parameter preprocessing subroutine is
1795 sent five arguments:
1796
1797 * The name of the class associated with the parameter
1798 This would be "My::Class" in the example above.
1799
1800 * The name of the parameter
1801 Either "DATA" or "PARAM" in the example above.
1802
1803 * A hash ref of the parameter's specifiers
1804 This is either a hash ref containing the ":Arg" attribute parame‐
1805 ters, or the hash ref paired to the parameter's key in the ":Ini‐
1806 tArgs" hash.
1807
1808 * The object being initialized
1809 * The parameter's value
1810 This is the value assigned to the parameter in the "->new()"
1811 method's argument list. If the parameter was not provided to
1812 "->new()", then "undef" will be sent.
1813
1814 The return value of the preprocessing subroutine will then be assigned
1815 to the parameter.
1816
1817 Be careful about what types of data the preprocessing subroutine tries
1818 to make use of "external" to the arguments supplied. For instance,
1819 because the order of parameter processing is not specified, the prepro‐
1820 cessing subroutine cannot rely on whether or not some other parameter
1821 is set. Such processing would need to be done in the ":Init" subrou‐
1822 tine. It can, however, make use of object data set by classes higher
1823 up in the class hierarchy. (That is why the object is provided as one
1824 of the arguments.)
1825
1826 Possible uses for parameter preprocessing include:
1827
1828 * Overriding the supplied value (or even deleting it by returning
1829 "undef")
1830 * Providing a dynamically-determined default value
1831
1832 Preprocess may be abbreviated to Preproc or Pre.
1833
1834 Set Accessor Preprocessing
1835
1836 You can specify a code ref (either in the form of an anonymous subrou‐
1837 tine, or a fully-qualified subroutine name) for a set/combined accessor
1838 that will be called on the arguments supplied to the accessor prior to
1839 its taking the usual actions of type checking and adding the data to
1840 the field. Here's an example:
1841
1842 package My::Class; {
1843 use Object::InsideOut;
1844
1845 my @data :Field
1846 :Acc('Name' => 'data', 'Preprocess' => \&My::Class::preproc);
1847
1848 # The set accessor preprocessing subroutine may be made 'Private'
1849 sub preproc :Private
1850 {
1851 my ($self, $field, @args) = @_;
1852
1853 # Preform preprocessing on the accessor's arguments
1854 ...
1855
1856 # Return result
1857 return ...;
1858 }
1859 }
1860
1861 As the above illustrates, the accessor preprocessing subroutine is sent
1862 the following arguments:
1863
1864 * The object used to invoke the accessor
1865 * A reference to the field associated with the accessor
1866 * The argument(s) sent to the accessor
1867 There will always be at least one argument.
1868
1869 Usually, the preprocessing subroutine should return just a single
1870 value. For fields declared as type "List", multiple values may be
1871 returned.
1872
1873 Following preprocessing, the set accessor will operate on whatever
1874 value(s) are returned by the proprocessing subroutine.
1875
1877 Object ID
1878
1879 By default, the ID of an object is derived from a sequence counter for
1880 the object's class hierarchy. This should suffice for nearly all cases
1881 of class development. If there is a special need for the module code
1882 to control the object ID (see Math::Random::MT::Auto as an example),
1883 then a subroutine labelled with the ":ID" attribute can be specified:
1884
1885 sub _id :ID
1886 {
1887 my $class = $_[0];
1888
1889 # Generate/determine a unique object ID
1890 ...
1891
1892 return ($id);
1893 }
1894
1895 The ID returned by your subroutine can be any kind of regular scalar
1896 (e.g., a string or a number). However, if the ID is something other
1897 than a low-valued integer, then you will have to architect all your
1898 classes using hashes for the object fields. See "HASH ONLY CLASSES"
1899 for details.
1900
1901 Within any class hierarchy, only one class may specify an ":ID" subrou‐
1902 tine.
1903
1904 Object Replication
1905
1906 Object replication occurs explicitly when the "->clone()" method is
1907 called on an object, and implicitly when threads are created in a
1908 threaded application. In nearly all cases, Object::InsideOut will take
1909 care of all the details for you.
1910
1911 In rare cases, a class may require special handling for object replica‐
1912 tion. It must then provide a subroutine labeled with the ":Replicate"
1913 attribute. This subroutine will be sent three arguments: The parent
1914 and the cloned objects, and a flag:
1915
1916 sub _replicate :Replicate
1917 {
1918 my ($parent, $clone, $flag) = @_;
1919
1920 # Special object replication processing
1921 if ($clone eq 'CLONE') {
1922 # Handling for thread cloning
1923 ...
1924 } elsif ($clone eq 'deep') {
1925 # Deep copy of the parent
1926 ...
1927 } else {
1928 # Shallow copying
1929 ...
1930 }
1931 }
1932
1933 In the case of thread cloning, $flag will be set to the 'CLONE', and
1934 the $parent object is just an un-blessed anonymous scalar reference
1935 that contains the ID for the object in the parent thread.
1936
1937 When invoked via the "->clone()" method, $flag will be either an empty
1938 string which denotes that a shallow copy is being produced for the
1939 clone, or $flag will be set to 'deep' indicating a deep copy is being
1940 produced.
1941
1942 The ":Replicate" subroutine only needs to deal with the special repli‐
1943 cation processing needed by the object: Object::InsideOut will handle
1944 all the other details.
1945
1946 Object Destruction
1947
1948 Object::InsideOut exports a "DESTROY" method to each class that deletes
1949 an object's data from the object field arrays (hashes). If a class
1950 requires additional destruction processing (e.g., closing filehandles),
1951 then it must provide a subroutine labeled with the ":Destroy"
1952 attribute. This subroutine will be sent the object that is being
1953 destroyed:
1954
1955 sub _destroy :Destroy
1956 {
1957 my $obj = $_[0];
1958
1959 # Special object destruction processing
1960 }
1961
1962 The ":Destroy" subroutine only needs to deal with the special destruc‐
1963 tion processing: The "DESTROY" method will handle all the other
1964 details of object destruction.
1965
1967 Object::InsideOut supports inheritance from foreign (i.e.,
1968 non-Object::InsideOut) classes. This means that your classes can
1969 inherit from other Perl class, and access their methods from your own
1970 objects.
1971
1972 One method of declaring foreign class inheritance is to add the class
1973 name to the Object::InsideOut declaration inside your package:
1974
1975 package My::Class; {
1976 use Object::InsideOut qw(Foreign::Class);
1977 ...
1978 }
1979
1980 This allows you to access the foreign class's static (i.e., class)
1981 methods from your own class. For example, suppose "Foreign::Class" has
1982 a class method called "foo". With the above, you can access that
1983 method using "My::Class->foo()" instead.
1984
1985 Multiple foreign inheritance is supported, as well:
1986
1987 package My::Class; {
1988 use Object::InsideOut qw(Foreign::Class Other::Foreign::Class);
1989 ...
1990 }
1991
1992 $self->inherit($obj, ...);
1993 To use object methods from foreign classes, an object must inherit
1994 from an object of that class. This would normally be done inside a
1995 class's ":Init" subroutine:
1996
1997 package My::Class; {
1998 use Object::InsideOut qw(Foreign::Class);
1999
2000 sub init :Init
2001 {
2002 my ($self, $args) = @_;
2003
2004 my $foreign_obj = Foreign::Class->new(...);
2005 $self->inherit($foreign_obj);
2006 }
2007 }
2008
2009 Thus, with the above, if "Foreign::Class" has an object method
2010 called "bar", you can call that method from your own objects:
2011
2012 package main;
2013
2014 my $obj = My::Class->new();
2015 $obj->bar();
2016
2017 Object::InsideOut's "AUTOLOAD" subroutine handles the dispatching
2018 of the "->bar()" method call using the internally held inherited
2019 object (in this case, $foreign_obj).
2020
2021 Multiple inheritance is supported, as well: You can call the
2022 "->inherit()" method multiple times, or make just one call with all
2023 the objects to be inherited from.
2024
2025 "->inherit()" is a restricted method. In other words, you cannot
2026 use it on an object outside of code belonging to the object's class
2027 tree (e.g., you can't call it from application code).
2028
2029 In the event of a method naming conflict, the "->inherit()" method
2030 can be called using its fully-qualified name:
2031
2032 $self->Object::InsideOut::inherit($obj);
2033
2034 my @objs = $self->heritage();
2035 my $obj = $self->heritage($class);
2036 my @objs = $self->heritage($class1, $class2, ...);
2037 Your class code can retrieve any inherited objects using the
2038 "->heritage()" method. When called without any arguments, it
2039 returns a list of any objects that were stored by the calling class
2040 using the calling object. In other words, if class "My::Class"
2041 uses object $obj to store foreign objects $fobj1 and $fobj2, then
2042 later on in class "My::Class", "$obj->heritage()" will return
2043 $fobj1 and $fobj2.
2044
2045 "->heritage()" can also be called with one or more class name argu‐
2046 ments. In this case, only objects of the specified class(es) are
2047 returned.
2048
2049 In the event of a method naming conflict, the "->heritage()" method
2050 can be called using its fully-qualified name:
2051
2052 my @objs = $self->Object::InsideOut::heritage();
2053
2054 $self->disinherit($class [, ...])
2055 $self->disinherit($obj [, ...])
2056 The "->disinherit()" method disassociates (i.e., deletes) the
2057 inheritance of foreign object(s) from an object. The foreign
2058 objects may be specified by class, or using the actual inherited
2059 object (retrieved via "->heritage()", for example).
2060
2061 The call is only effective when called inside the class code that
2062 established the initial inheritance. In other words, if an inheri‐
2063 tance is set up inside a class, then disinheritance can only be
2064 done from inside that class.
2065
2066 In the event of a method naming conflict, the "->disinherit()"
2067 method can be called using its fully-qualified name:
2068
2069 $self->Object::InsideOut::disinherit($obj [, ...])
2070
2071 NOTE: With foreign inheritance, you only have access to class and
2072 object methods. The encapsulation of the inherited objects is strong,
2073 meaning that only the class where the inheritance takes place has
2074 direct access to the inherited object. If access to the inherited
2075 objects themselves, or their internal hash fields (in the case of
2076 blessed hash objects), is needed outside the class, then you'll need to
2077 write your own accessors for that.
2078
2079 LIMITATION: You cannot use fully-qualified method names to access for‐
2080 eign methods (when encapsulated foreign objects are involved). Thus,
2081 the following will not work:
2082
2083 my $obj = My::Class->new();
2084 $obj->Foreign::Class::bar();
2085
2086 Normally, you shouldn't ever need to do the above: "$obj->bar()" would
2087 suffice.
2088
2089 The only time this may be an issue is when the native class overrides
2090 an inherited foreign class's method (e.g., "My::Class" has its own
2091 "->bar()" method). Such overridden methods are not directly callable.
2092 If such overriding is intentional, then this should not be an issue:
2093 No one should be writing code that tries to by-pass the override. How‐
2094 ever, if the overriding is accidently, then either the native method
2095 should be renamed, or the native class should provide a wrapper method
2096 so that the functionality of the overridden method is made available
2097 under a different name.
2098
2099 "use base" and Fully-qualified Method Names
2100
2101 The foreign inheritance methodology handled by the above is predicated
2102 on non-Object::InsideOut classes that generate their own objects and
2103 expect their object methods to be invoked via those objects.
2104
2105 There are exceptions to this rule:
2106
2107 1. Foreign object methods that expect to be invoked via the inheriting
2108 class's object, or foreign object methods that don't care how they are
2109 invoked (i.e., they don't make reference to the invoking object).
2110 This is the case where a class provides auxiliary methods for your
2111 objects, but from which you don't actually create any objects
2112 (i.e., there is no corresponding foreign object, and
2113 "$obj->inherit($foreign)" is not used.)
2114
2115 In this case, you can either:
2116
2117 a. Declare the foreign class using the standard method (i.e.,
2118 "use Object::InsideOut qw(Foreign::Class);"), and invoke its meth‐
2119 ods using their full path (e.g., "$obj->For‐
2120 eign::Class::method();"); or
2121
2122 b. You can use the base pragma so that you don't have to use the
2123 full path for foreign methods.
2124
2125 package My::Class; {
2126 use Object::InsideOut;
2127 use base 'Foreign::Class';
2128 ...
2129 }
2130
2131 The former scheme is faster.
2132
2133 2. Foreign class methods that expect to be invoked via the inheriting
2134 class.
2135 As with the above, you can either invoke the class methods using
2136 their full path (e.g., "My::Class->Foreign::Class::method();"), or
2137 you can "use base" so that you don't have to use the full path.
2138 Again, using the full path is faster.
2139
2140 Class::Singleton is an example of this type of class.
2141
2142 3. Class methods that don't care how they are invoked (i.e., they don't
2143 make reference to the invoking class).
2144 In this case, you can either use "use Object::InsideOut qw(For‐
2145 eign::Class);" for consistency, or use "use base qw(For‐
2146 eign::Class);" if (slightly) better performance is needed.
2147
2148 If you're not familiar with the inner workings of the foreign class
2149 such that you don't know if or which of the above exceptions applies,
2150 then the formulaic approach would be to first use the documented method
2151 for foreign inheritance (i.e., "use Object::InsideOut qw(For‐
2152 eign::Class);"). If that works, then I strongly recommend that you
2153 just use that approach unless you have a good reason not to. If it
2154 doesn't work, then try "use base".
2155
2157 Object::InsideOut provides an introspection API that allow you to
2158 obtain metadata on a class's hierarchy, constructor parameters, and
2159 methods.
2160
2161 my $meta = My::Class->meta();
2162 my $meta = $obj->meta();
2163 The "->meta()" method, which is exported by Object::InsideOut to
2164 each class, returns an Object::InsideOut::Metadata object which can
2165 then be queried for information about the invoking class or invok‐
2166 ing object's class:
2167
2168 # Get an object's class hierarchy
2169 my @classes = $obj->meta()->get_classes();
2170
2171 # Get info on the args for a class's constructor (i.e., ->new() parameters)
2172 my %args = My::Class->meta()->get_args();
2173
2174 # Get info on the methods that can be called by an object
2175 my %methods = $obj->meta()->get_methods();
2176
2177 My::Class->isa();
2178 $obj->isa();
2179 When called in an array context, calling "->isa()" without any
2180 arguments on an Object::InsideOut class or object returns a list of
2181 the classes in the class hierarchy for that class or object, and is
2182 equivalent to:
2183
2184 my @classes = $obj->meta()->get_classes();
2185
2186 When called in a scalar context, it returns an array ref containing
2187 the classes.
2188
2189 My::Class->can();
2190 $obj->can();
2191 When called in an array context, calling "->can()" without any
2192 arguments on an Object::InsideOut class or object returns a list of
2193 the method names for that class or object, and is equivalent to:
2194
2195 my %methods = $obj->meta()->get_methods();
2196 my @methods = keys(%methods);
2197
2198 When called in a scalar context, it returns an array ref containing
2199 the method names.
2200
2201 See Object::InsideOut::Metadata for more details.
2202
2204 For Perl 5.8.1 and later, Object::InsideOut fully supports threads
2205 (i.e., is thread safe), and supports the sharing of Object::InsideOut
2206 objects between threads using threads::shared.
2207
2208 To use Object::InsideOut in a threaded application, you must put
2209 "use threads;" at the beginning of the application. (The use of
2210 "require threads;" after the program is running is not supported.) If
2211 object sharing is to be utilized, then "use threads::shared;" should
2212 follow.
2213
2214 If you just "use threads;", then objects from one thread will be copied
2215 and made available in a child thread.
2216
2217 The addition of "use threads::shared;" in and of itself does not alter
2218 the behavior of Object::InsideOut objects. The default behavior is to
2219 not share objects between threads (i.e., they act the same as with
2220 "use threads;" alone).
2221
2222 To enable the sharing of objects between threads, you must specify
2223 which classes will be involved with thread object sharing. There are
2224 two methods for doing this. The first involves setting a "::shared"
2225 variable (inside a "BEGIN" block) for the class prior to its use:
2226
2227 use threads;
2228 use threads::shared;
2229
2230 BEGIN {
2231 $My::Class::shared = 1;
2232 }
2233 use My::Class;
2234
2235 The other method is for a class to add a ":SHARED" flag to its
2236 "use Object::InsideOut ..." declaration:
2237
2238 package My::Class; {
2239 use Object::InsideOut ':SHARED';
2240 ...
2241 }
2242
2243 When either sharing flag is set for one class in an object hierarchy,
2244 then all the classes in the hierarchy are affected.
2245
2246 If a class cannot support thread object sharing (e.g., one of the
2247 object fields contains code refs [which Perl cannot share between
2248 threads]), it should specifically declare this fact:
2249
2250 package My::Class; {
2251 use Object::InsideOut ':NOT_SHARED';
2252 ...
2253 }
2254
2255 However, you cannot mix thread object sharing classes with non-sharing
2256 classes in the same class hierarchy:
2257
2258 use threads;
2259 use threads::shared;
2260
2261 package My::Class; {
2262 use Object::InsideOut ':SHARED';
2263 ...
2264 }
2265
2266 package Other::Class; {
2267 use Object::InsideOut ':NOT_SHARED';
2268 ...
2269 }
2270
2271 package My::Derived; {
2272 use Object::InsideOut qw(My::Class Other::Class); # ERROR!
2273 ...
2274 }
2275
2276 Here is a complete example with thread object sharing enabled:
2277
2278 use threads;
2279 use threads::shared;
2280
2281 package My::Class; {
2282 use Object::InsideOut ':SHARED';
2283
2284 # One list-type field
2285 my @data :Field :Type(List) :Acc(data);
2286 }
2287
2288 package main;
2289
2290 # New object
2291 my $obj = My::Class->new();
2292
2293 # Set the object's 'data' field
2294 $obj->data(qw(foo bar baz));
2295
2296 # Print out the object's data
2297 print(join(', ', @{$obj->data()}), "\n"); # "foo, bar, baz"
2298
2299 # Create a thread and manipulate the object's data
2300 my $rc = threads->create(
2301 sub {
2302 # Read the object's data
2303 my $data = $obj->data();
2304 # Print out the object's data
2305 print(join(', ', @{$data}), "\n"); # "foo, bar, baz"
2306 # Change the object's data
2307 $obj->data(@$data[1..2], 'zooks');
2308 # Print out the object's modified data
2309 print(join(', ', @{$obj->data()}), "\n"); # "bar, baz, zooks"
2310 return (1);
2311 }
2312 )->join();
2313
2314 # Show that changes in the object are visible in the parent thread
2315 # I.e., this shows that the object was indeed shared between threads
2316 print(join(', ', @{$obj->data()}), "\n"); # "bar, baz, zooks"
2317
2319 For performance considerations, it is recommended that arrays be used
2320 for class fields whenever possible. The only time when hash-bases
2321 fields are required is when a class must provide its own "Object ID" in
2322 object ID, and those IDs are something other than low-valued integers.
2323 In this case, hashes must be used for fields not only in the class that
2324 defines the object ID subroutine, but also in every class in any class
2325 hierarchy that include such a class.
2326
2327 The hash only requirement can be enforced by adding the ":HASH_ONLY"
2328 flag to a class's "use Object::InsideOut ..." declaration:
2329
2330 package My::Class; {
2331 use Object::InsideOut ':hash_only';
2332
2333 ...
2334 }
2335
2336 This will cause Object::Inside to check every class in any class hier‐
2337 archy that includes such flagged classes to make sure their fields are
2338 hashes and not arrays. It will also fail any ->create_field() call
2339 that tries to create an array-based field in any such class.
2340
2342 In the default case where Object::InsideOut provides object IDs that
2343 are sequential integers, it is possible to hack together a fake
2344 Object::InsideOut object, and so gain access to another object's data:
2345
2346 my $fake = bless(\do{my $scalar}, 'Some::Class');
2347 $$fake = 86; # ID of another object
2348 my $stolen = $fake->get_data();
2349
2350 Why anyone would try to do this is unknown. How this could be used for
2351 any sort of malicious exploitation is also unknown. However, if pre‐
2352 venting this sort of security issue is a requirement, it can be accom‐
2353 plished by giving your objects a random ID, and thus prevent other code
2354 from creating fake objects by guessing at the IDs.
2355
2356 To do this, your class must provide an :ID subroutine that returns ran‐
2357 dom values, and the class must be flagged as :HASH_ONLY. One simple
2358 way of providing random IDs it to use random integers provided by
2359 Math::Random::MT::Auto, as illustrated below:
2360
2361 package My::Class; {
2362 use Object::InsideOut ':HASH_ONLY';
2363 use Math::Random::MT::Auto 'irand';
2364
2365 sub _id :ID { irand(); }
2366
2367 ...
2368 }
2369
2371 Object::InsideOut uses attribute 'modify' handlers as described in
2372 "Package-specific Attribute Handling" in attributes, and provides a
2373 mechanism for adding attibute handlers to your own classes. Instead of
2374 naming your attribute handler as "MODIFY_*_ATTRIBUTES", name it some‐
2375 thing else and then label it with the ":MODIFY_*_ATTRIBUTES" attribute
2376 (or ":MOD_*_ATTRS" for short). Your handler should work just as
2377 described in "Package-specific Attribute Handling" in attributes with
2378 regard to its input arguments, and must return a list of the attributes
2379 which were not recognized by your handler. Here's an example:
2380
2381 package My::Class; {
2382 use Object::InsideOut;
2383
2384 sub _scalar_attrs :MOD_SCALAR_ATTRS
2385 {
2386 my ($pkg, $scalar, @attrs) = @_;
2387 my @unused_attrs; # List of any unhandled attributes
2388
2389 while (my $attr = shift(@attrs)) {
2390 if ($attr =~ /.../) {
2391 # Handle attribute
2392 ...
2393 } else {
2394 # We don't handle this attribute
2395 push(@unused_attrs, $attr);
2396 }
2397 }
2398
2399 return (@unused_attrs); # Pass along unhandled attributes
2400 }
2401 }
2402
2403 Attribute 'modify' handlers are called upwards through the class hier‐
2404 archy (i.e., bottom up). This provides child classes with the capabil‐
2405 ity to override the handling of attributes by parent classes, or to add
2406 attributes (via the returned list of unhandled attributes) for parent
2407 classes to process.
2408
2409 Attribute 'modify' handlers should be located at the beginning of a
2410 package, or at least before any use of attibutes on the corresponding
2411 type of variable or subroutine:
2412
2413 package My::Class; {
2414 use Object::InsideOut;
2415
2416 sub _array_attrs :MOD_ARRAY_ATTRS
2417 {
2418 ...
2419 }
2420
2421 my @my_array :MyArrayAttr;
2422 }
2423
2424 For attribute 'fetch' handlers, follow the same procedures: Label the
2425 subroutine with the ":FETCH_*_ATTRIBUTES" attribute (or
2426 ":FETCH_*_ATTRS" for short). Contrary to the documentation in "Pack‐
2427 age-specific Attribute Handling" in attributes, attribute 'fetch' han‐
2428 dlers receive two arguments: The relevant package name, and a reference
2429 to a variable or subroutine for which package-defined attributes are
2430 desired.
2431
2432 Attribute handlers are normal rendered hidden.
2433
2435 Usage With "Exporter"
2436
2437 It is possible to use Exporter to export functions from one inside-out
2438 object class to another:
2439
2440 use strict;
2441 use warnings;
2442
2443 package Foo; {
2444 use Object::InsideOut 'Exporter';
2445 BEGIN {
2446 our @EXPORT_OK = qw(foo_name);
2447 }
2448
2449 sub foo_name
2450 {
2451 return (__PACKAGE__);
2452 }
2453 }
2454
2455 package Bar; {
2456 use Object::InsideOut 'Foo' => [ qw(foo_name) ];
2457
2458 sub get_foo_name
2459 {
2460 return (foo_name());
2461 }
2462 }
2463
2464 package main;
2465
2466 print("Bar got Foo's name as '", Bar::get_foo_name(), "'\n");
2467
2468 Note that the "BEGIN" block is needed to ensure that the Exporter sym‐
2469 bol arrays (in this case @EXPORT_OK) get populated properly.
2470
2471 Usage With "require" and "mod_perl"
2472
2473 Object::InsideOut usage under mod_perl and with runtime-loaded classes
2474 is supported automatically; no special coding is required.
2475
2476 Singleton Classes
2477
2478 A singleton class is a case where you would provide your own "->new()"
2479 method that in turn calls Object::InsideOut's "->new()" method:
2480
2481 package My::Class; {
2482 use Object::InsideOut;
2483
2484 my $singleton;
2485
2486 sub new {
2487 my $thing = shift;
2488 if (! $singleton) {
2489 $singleton = $thing->Object::InsideOut::new(@_);
2490 }
2491 return ($singleton);
2492 }
2493 }
2494
2496 Object::InsideOut uses "Exception::Class" for reporting errors. The
2497 base error class for this module is "OIO". Here is an example of the
2498 basic manner for trapping and handling errors:
2499
2500 my $obj;
2501 eval { $obj = My::Class->new(); };
2502 if (my $e = OIO->caught()) {
2503 print(STDERR "Failure creating object: $e\n");
2504 exit(1);
2505 }
2506
2507 I have tried to make the messages and information returned by the error
2508 objects as informative as possible. Suggested improvements are wel‐
2509 come. Also, please bring to my attention any conditions that you
2510 encounter where an error occurs as a result of Object::InsideOut code
2511 that doesn't generate an Exception::Class object. Here is one such
2512 error:
2513
2514 Invalid ARRAY/HASH attribute
2515 This error indicates you forgot the following in your class's code:
2516
2517 use Object::InsideOut qw(Parent::Class ...);
2518
2519 Object::InsideOut installs a "__DIE__" handler (see "die LIST" in perl‐
2520 func and "eval BLOCK" in perlfunc) to catch any errant exceptions from
2521 class-specific code, namely, ":Init", ":Replicate", ":Destroy", etc.
2522 subroutines. This handler may interfer with code that uses the "die"
2523 function as a method of flow control for leaving an "eval" block. The
2524 proper method for handling this is to localize $SIG{'__DIE__'} inside
2525 the "eval" block:
2526
2527 eval {
2528 local $SIG{'__DIE__'}; # Suppress any existing __DIE__ handler
2529 ...
2530 die({'found' => 1}) if $found; # Leave the eval block
2531 ...
2532 };
2533 if ($@) {
2534 die unless (ref($@) && $@->{'found'}); # Propagate any 'real' error
2535 # Handle 'found' case
2536 ...
2537 }
2538 # Handle 'not found' case
2539
2540 Similarly, if calling code from other modules that work as above, but
2541 without localizing $SIG{'__DIE__'}, you can workaround this deficiency
2542 with your own "eval" block:
2543
2544 eval {
2545 local $SIG{'__DIE__'}; # Suppress any existing __DIE__ handler
2546 Some::Module::func(); # Call function that fails to localize
2547 };
2548 if ($@) {
2549 # Handle caught exception
2550 }
2551
2552 In addition, you should file a bug report against the offending module
2553 along with a patch that adds the missing "local $SIG{'__DIE__'};"
2554 statement.
2555
2557 You cannot overload an object to a scalar context (i.e., can't
2558 ":SCALARIFY").
2559
2560 You cannot use two instances of the same class with mixed thread object
2561 sharing in same application.
2562
2563 Cannot use attributes on subroutine stubs (i.e., forward declaration
2564 without later definition) with ":Automethod":
2565
2566 package My::Class; {
2567 sub method :Private; # Will not work
2568
2569 sub _automethod :Automethod
2570 {
2571 # Code to handle call to 'method' stub
2572 }
2573 }
2574
2575 Due to limitations in the Perl parser, the entirety of any one
2576 attribute must be on a single line. (However, multiple attributes may
2577 appear on separate lines.)
2578
2579 If a set accessor accepts scalars, then you can store any inside-out
2580 object type in it. If its "Type" is set to "HASH", then it can store
2581 any blessed hash object.
2582
2583 Returning objects from threads does not work:
2584
2585 my $obj = threads->create(sub { return (Foo->new()); })->join(); # BAD
2586
2587 Instead, use thread object sharing, create the object before launching
2588 the thread, and then manipulate the object inside the thread:
2589
2590 my $obj = Foo->new(); # Class 'Foo' is set ':SHARED'
2591 threads->create(sub { $obj->set_data('bar'); })->join();
2592 my $data = $obj->get_data();
2593
2594 There are bugs associated with threads::shared that may prevent you
2595 from using foreign inheritance with shared objects, or storing objects
2596 inside of shared objects.
2597
2598 For Perl 5.6.0 through 5.8.0, a Perl bug prevents package variables
2599 (e.g., object attribute arrays/hashes) from being referenced properly
2600 from subroutine refs returned by an ":Automethod" subroutine. For Perl
2601 5.8.0 there is no workaround: This bug causes Perl to core dump. For
2602 Perl 5.6.0 through 5.6.2, the workaround is to create a ref to the
2603 required variable inside the ":Automethod" subroutine, and use that
2604 inside the subroutine ref:
2605
2606 package My::Class; {
2607 use Object::InsideOut;
2608
2609 my %data;
2610
2611 sub auto :Automethod
2612 {
2613 my $self = $_[0];
2614 my $name = $_;
2615
2616 my $data = \%data; # Workaround for 5.6.X bug
2617
2618 return sub {
2619 my $self = shift;
2620 if (! @_) {
2621 return ($$data{$name});
2622 }
2623 $$data{$name} = shift;
2624 };
2625 }
2626 }
2627
2628 For Perl 5.8.1 through 5.8.4, a Perl bug produces spurious warning mes‐
2629 sages when threads are destroyed. These messages are innocuous, and
2630 can be suppressed by adding the following to your application code:
2631
2632 $SIG{'__WARN__'} = sub {
2633 if ($_[0] !~ /^Attempt to free unreferenced scalar/) {
2634 print(STDERR @_);
2635 }
2636 };
2637
2638 A better solution would be to upgrade threads and threads::shared from
2639 CPAN, especially if you encounter other problems associated with
2640 threads.
2641
2642 For Perl 5.8.4 and 5.8.5, the "Storable" feature does not work due to a
2643 Perl bug. Use Object::InsideOut v1.33 if needed.
2644
2645 Devel::StackTrace (used by Exception::Class) makes use of the DB names‐
2646 pace. As a consequence, Object::InsideOut thinks that "package DB" is
2647 already loaded. Therefore, if you create a class called DB that is
2648 sub-classed by other packages, you may need to "require" it as follows:
2649
2650 package DB::Sub; {
2651 require DB;
2652 use Object::InsideOut qw(DB);
2653 ...
2654 }
2655
2656 View existing bug reports at, and submit any new bugs, problems,
2657 patches, etc. to:
2658 <http://rt.cpan.org/NoAuth/Bugs.html?Dist=Object-InsideOut>
2659
2661 Perl 5.6.0 or later
2662
2663 Exception::Class v1.22 or later
2664
2665 Scalar::Util v1.10 or later. It is possible to install a pure perl
2666 version of Scalar::Util, however, it will be missing the weaken() func‐
2667 tion which is needed by Object::InsideOut. You'll need to upgrade your
2668 version of Scalar::Util to one that supports its "XS" code.
2669
2670 Test::More v0.50 or later (for installation)
2671
2672 Optionally, Want for ":lvalue Accessors".
2673
2675 Object::InsideOut Discussion Forum on CPAN: <http://www.cpanfo‐
2676 rum.com/dist/Object-InsideOut>
2677
2678 Annotated POD for Object::InsideOut: <http://annocpan.org/~JDHED‐
2679 DEN/Object-InsideOut-2.06/lib/Object/InsideOut.pm>
2680
2681 Inside-out Object Model: <http://www.perlmonks.org/?node_id=219378>,
2682 <http://www.perlmonks.org/?node_id=483162>, <http://www.perl‐
2683 monks.org/?node_id=515650>, Chapters 15 and 16 of Perl Best Practices
2684 by Damian Conway
2685
2686 Object::InsideOut::Metadata
2687
2688 Storable, <Exception:Class>, Want, attributes, overload
2689
2691 Abigail <perl AT abigail DOT nl> for inside-out objects in general.
2692
2693 Damian Conway <dconway AT cpan DOT org> for Class::Std.
2694
2695 David A. Golden <dagolden AT cpan DOT org> for thread handling for
2696 inside-out objects.
2697
2698 Dan Kubb <dan.kubb-cpan AT autopilotmarketing DOT com> for ":Chained"
2699 methods.
2700
2702 Jerry D. Hedden, <jdhedden AT cpan DOT org>
2703
2705 Copyright 2005, 2006 Jerry D. Hedden. All rights reserved.
2706
2707 This program is free software; you can redistribute it and/or modify it
2708 under the same terms as Perl itself.
2709
2710
2711
2712perl v5.8.8 2006-10-09 Object::InsideOut(3)