Why not adopt me?
NAME
Data::Object::AutoWrap - Autogenerate accessors for R/O object data
VERSION
This document describes Data::Object::AutoWrap version 0.02
SYNOPSIS
package MyData;
# Our data is in $self->{data}
use Data::Object::AutoWrap qw( data );
sub new {
my ( $class, $data ) = @_;
bless { data => $data }, $class;
}
# ... and then later, elsewhere ...
my $d = MyData->new( { foo => 1, bar => [ 1, 2, 3 ] } );
print $d->foo; # prints "1"
print $d->bar( 2 ); # prints "3"
DESCRIPTION
This is an experimental module designed to simplify the implementation of read-only objects with value semantics.
Objects created using Data::Objects::AutoWrap
are bound to a Perl data structure. The automatically provide read only accessor methods for the elements of that structure.
Declaring an autowrapped class
As in the example above an autowrapped class is created by adding the line
use Data::Object::AutoWrap qw( fieldname );
We assume (for now) that the class is hash based and that this hash contains a key called fieldname
. The corresponding value is the data structure that will be exposed as the module's interface. The 'root' level of this data structure must itself be a hash - we need the key names so we can generate corresponding methods. Below the root of the data structure any type may be used.
If the fieldname
is omitted the entire contents of the object's hash will be exposed.
Accessors
For each key in the value hash a corresponding read-only accessor is made available. In order for these accessors to be callable the key names must also be valid Perl method names - it's OK to have a key called '*(&!*(&£' but it's rather tricky to call the corresponding accessor.
The generated accessors are AUTOLOADed. As a result the bound data structure may be a different shape for each instance of the containing class: the accessors are virtual - they don't actually exist in the module's symbol table.
In the following examples we'll assume that we have a Data::Object::AutoWrap
based class called MyData
that gets the data structure to bind to as the argument to its constructor. The code fragment in the synopsis is a suitable implementation of such a class.
Scalar Accessors
Any scalars in the hash get an accessor that takes no arguments and returns the corresponding value:
my $sc = MyData->new({ flimp_count => 1 });
my $fc = $sc->flimp_count; # gets 1
An error is raised if arguments are passed to the accessor.
Hash Accessors
Any nested hashes in the data structure get accessors that return recursively wrapped hashes. That means that this will work:
my $hc = MyData->new(
{
person => {
name => 'Andy',
job => 'Perl baiter',
},
}
);
print $hc->person->job; # prints "Perl baiter"
Array accessors
The accessor for array values accepts an optional subscript:
my $ac = MyData->new( { list => [ 12, 27, 36, 43, ] } );
my $third = $ac->list( 3 ); # gets 36
Called in a list context with no arguments the accessor for an array returns that array:
my @list = $ac->list; # gets the whole list
Accessors for other types
Anything that's not an array or a hash gets the scalar accessor - so things like globs will also be accessible.
Accessor parameters
Array and hash accessors can accept more than one parameter. For example if you have an array of arrays you can subscript into it like this:
my $gc = MyData->new(
{
grid => [
[ 0, 1, 2, 3 ],
[ 4, 5, 6, 7 ],
[ 8, 9, 10, 11 ],
[ 12, 13, 14, 15 ],
],
}
);
my $dot = $gc->grid( 3, 4 ); # gets 11
In general any parameters specify a path through the data structure:
my $hc = MyData->new(
{
deep => {
smash => 'pumpkins',
eviscerate => [ 'a', 'b', 'c' ],
lament => { fine => 'camels' }
}
}
);
print $hc->deep( 'smash' ); # 'pumpkins'
print $hc->deep( 'eviscerate', 1 ); # 'b'
print $hc->deep( 'lament', 'fine' ); # 'camels'
print $hc->deep->lament->fine; # also 'camels'
print $hc->deep( 'lament' )->fine; # 'camels' again
print $hc->deep->lament( 'fine' ); # more 'camels'
CAVEATS
This is experimental code. Don't be using it in, for example, a life support system, ATM or space shuttle.
AUTOLOAD
Data::Object::AutoWrap
injects an AUTOLOAD
handler into the package from which it is used. It doesn't care about any existing AUTOLOAD
or any that might be provided by a superclass. Given that it's designed for the implementation of simple, value like objects this shouldn't be a problem - but you've been warned.
Performance
It's slow. Slow as mollasses in an igloo. Last time I checked the autogenerated accessors are something like fifteen times slower than the simplest hand wrought accessor.
This can probably be improved.
CONFIGURATION AND ENVIRONMENT
Data::Object::AutoWrap requires no configuration files or environment variables.
DEPENDENCIES
None.
INCOMPATIBILITIES
None reported.
BUGS AND LIMITATIONS
Yes, probably.
Please report any bugs or feature requests to bug-data-object-autowrap@rt.cpan.org
, or through the web interface at http://rt.cpan.org.
AUTHOR
Andy Armstrong <andy.armstrong@messagesystems.com>
LICENCE AND COPYRIGHT
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.
Copyright (c) 2008, Message Systems, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name Message Systems, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 71:
Non-ASCII character seen before =encoding in ''*(&!*(&£''. Assuming UTF-8