Object::InsideOut - Comprehensive inside-out object support module
This document describes Object::InsideOut version 3.98:
Object data is enclosed within the class's code and is accessible only through the class-defined interface.
Inheritance using blessed hash classes can lead to conflicts if any classes use the same name for a field (i.e., hash key). Inside-out objects are immune to this problem because object data is stored inside each class's package, and not in the object itself.{$$self} = $value; # Also causes a compile-time error
Object::InsideOut offers all the capabilities of other inside-out object modules with the following additional key advantages:
When using arrays to store object data, Object::InsideOut objects are as much as 40% faster than blessed hash objects for fetching and setting data, and even with hashes they are still several percent faster than blessed hash objects.
Object::InsideOut is thread safe, and thoroughly supports sharing objects between threads using threads::shared.
Allows control over object ID specification, accessor naming, parameter name matching, and much more.
Supports classes that may be loaded at runtime (i.e., using
eval { require ...; };). This makes it usable from within mod_perl, as well. Also supports additions to class hierarchies, and dynamic creation of object fields during runtime.
Object::InsideOut uses Exception::Class for handling errors in an OO-compatible manner.
Object::InsideOut has built-in support for object dumping and reloading that can be accomplished in either an automated fashion or through the use of class-supplied subroutines. Serialization using Storable is also supported.
Object::InsideOut allows classes to inherit from foreign (i.e., non-Object::InsideOut) classes, thus allowing you to sub-class other Perl class, and access their methods from your own objects.
Obtain constructor parameters and method metadata for Object::InsideOut.
In class code, data can be fetched directly from an object's field array (hash) using the object's ID:
$data = $field[$$self]; # or $data = $field{$$self};.
Data processed by the
:Init sub.
The
:InitArgs hash and the
:Arg attribute on fields act as filters that constrain which initialization parameters are and are not sent to the
:Init subroutine. If, however, a class does not have an
:InitArgs hash and does not use the
:Arg attribute on any of its fields, then its
:Init subroutine (if it exists, of course) will get all the initialization parameters supplied to the
->new() method..
For optional parameters, defaults can be specified for field-specific parameters using either of these syntaxes:
my @data :Field :Arg('Name' => 'data', 'Default' => 'foo'); my @info :Field :Arg(info) :Default('bar');' }). } }, );:
->new()method are processed for
:Argfield attributes and entries in the
:InitArgshash:
:InitArgshash are added for subsequent processing by the
:Initsubroutine.
:InitArgshash.
->new()that were not handled in the above. (See next section.).
If you add the following construct to the start of your application:
BEGIN { no warnings 'once'; $OIO::Args::Unhandled::WARN_ONLY = 1; }
then unhandled parameters will only generate warnings rather than causing exceptions to be thrown.

Prev or
Prior as synonyms for
Old.
Finally, you can specify that the accessor should return the object itself:
my @data :Field :Std('Name' => 'data', 'Ret' => 'Object');
Object may be abbreviated to
Obj, and is also synonymous with
Self.');..
In the same vein as describe above, access to methods can be narrowed by use of
:Restricted and
:Private attributes.
sub foo :Restricted { my $self = shift; ... }
Without either of these attributes, most methods have public access. If desired, you may explicitly label them with the
:Public attribute..)
Object::InsideOut can be directed to add type-checking code to the set/combined accessors it generates, and to perform type checking on object initialization parameters.:
Permits anything that is not a reference.
Can also be specified as
Num or
Number. This uses Scalar::Util::looks_like_number() to test the input value.:
Same as for the basic type above.
Same as for the basic type above.
Same as for the basic type below.
Any reference type (in all caps) as returned by ref()).
This specifies that only a single array reference is permitted. Can also be specified as
ARRAYref.
When specified, the contents of the array ref are checked against the specified subtype as per the above.
This type permits an accessor to accept multiple
key => value pairs (which are then placed in a hash ref) or a single hash ref.
For object initialization parameters, only a single ref is permitted.
This specifies that only a single hash reference is permitted. Can also be specified as
HASHref.
This type permits an accessor to accept a single scalar reference. Can also be specified as
SCALARref.
This permits only an object of the specified class, or one of its sub-classes (i.e., type checking is done using
->isa()). For example,
My::Class. The class name
UNIVERSAL permits any object. The class name
Object::InsideOut permits any object generated by an Object::InsideOut class.)); } }
:InitParameters pairs for the object's fields. For example:
[ 'My::Class::Sub', { 'My::Class' => { 'data' => 'value' }, 'My::Class::Sub' => { 'life' => 42 } } ]
The name for an object field (data and life in the example above) can be specified by adding the
:Name attribute to the field:
my @life :Field :Name(life);
If the
:Name attribute is not used, then the name for a field will be either the name associated with an
:All or
:Arg attribute,();
Object::InsideOut->pump() takes the output from the
->dump() method, and returns an object that is created using that data. If
$data is the array ref returned by using
$obj->dump(), then the data is inserted directly into the corresponding fields for each class in the object's class hierarchy. If
$data attributes to the
:Field declarations (see above), or provide a
:Dumper/
:Pumper pair of subroutines as described below.
Dynamically altering a class (e.g., using ->create_field()) after objects have been dumped will result in
undef fields attribute. This subroutine will be sent the object that is being dumped. It may then return any type of scalar the developer deems appropriate. Usually, this would be a hash ref containing
key => value pairs for the object's fields. For example:
my @data :Field; sub _dump :Dumper { my $obj = $_[0]; my %field_data; $field_data{'data'} = $data[$$obj]; return (\%field_data); }
Just be sure not to call your
:Dumper subroutine
dump as that is the name of the dump method exported by Object::InsideOut as explained above.
:PumperSubroutine Attribute
If a class supplies a
:Dumper subroutine, it will most likely need to provide a complementary
:Pumper labeled subroutine that will be used as part of creating an object from dumped data using
Object::InsideOut->pump(). The subroutine will be supplied the new object that is being created, and whatever scalar was returned by the
:Dumper subroutine. The corresponding
:Pumper for the example
:Dumper above would be:
sub _pump :Pumper { my ($obj, $field_data) = @_; $obj->set(\@data, $field_data->{'data'}); };
NOTE: The caveats discussed above for the
->pump() method are also applicable when using the Storable module..
Object cloning can be controlled at the field level such that specified fields are deeply copied when
->clone() is called without any arguments. This is done by adding the
:Deep attribute to the field:
my @data :Field :Deep;:
$self->set(\@field, $data); Scalar::Util::weaken($field[$$self]);
(This is another reason why the
->set() method is recommended for setting field data within class code.):
This would be
My::Class in the example above.
Either
DATA or
PARAM in the example above.
This is either a hash ref containing the
:Arg attribute parameters, or the hash ref paired to the parameter's key in the
:InitArgs hash.
This is the value assigned to the parameter in the
->new() method's argument list. If the parameter was not provided to
->new(), then
undef will:
undef)
Preprocess may be abbreviated to Preproc or Pre.); ... }
To use object methods from foreign classes, an object must inherit from an object of that class. This would normally be done inside a class's
:Init subroutine:
package My::Class; { use Object::InsideOut qw(Foreign::Class); sub init :Init { my ($self, $args) = @_; my $foreign_obj = Foreign::Class->new(...); $self->inherit($foreign_obj); } }
Thus, with the above, if
Foreign::Class has an object method called
bar, you can call that method from your own objects:
package main; my $obj = My::Class->new(); $obj->bar();
Object::InsideOut's
AUTOLOAD sub);
Your class code can retrieve any inherited objects using the
->heritage() method. When called without any arguments, it returns a list of any objects that were stored by the calling class using the calling object. In other words, if class
My::Class uses object
$obj to store foreign objects
$fobj1 and
$fobj2, then later on in class
My::Class,
$obj->heritage() will return
$fobj1and Fully-qualified Method Names
The foreign inheritance methodology handled by the above is predicated on non-Object::InsideOut classes that generate their own objects and expect their object methods to be invoked via those objects.
There are exceptions to this rule:.
As with the above, you can either invoke the class methods using their full path (e.g.,
My::Class->Foreign::Class::method();), or you can
use base so that you don't have to use the full path. Again, using the full path is faster.
Class::Singleton is an example of this type of.
For Perl 5.8.0 and later, Object::InsideOut provides an introspection API that allow you to obtain metadata on a class's hierarchy, constructor parameters, and methods..
require..:
It is possible to install a pure perl version of Scalar::Util, however, it will be missing the weaken() function which is needed by Object::InsideOut. You'll need to upgrade your version of Scalar::Util to one that supports its
XS code.
Needed for testing during installation.
Optional. Provides support for ":lvalue Accessors"..
Object::InsideOut Discussion Forum on CPAN:
Inside-out Object Model:,,,, Chapters 15 and 16 of Perl Best Practices by Damian Conway
Object::InsideOut::Metadata
Storable, Exception:Class, Want, Math::Random::MT::Auto, attributes, overload.
Jerry D. Hedden, <jdhedden AT cpan DOT org>
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
A Japanese translation of this documentation by TSUJII, Naofumi <tsun DOT nt AT gmail DOT com> is available at.