Object::ArrayType::New - Inject constants and constructor for ARRAY-type objects
package MyObject; use strict; use warnings; use Object::ArrayType::New [ foo => 'FOO', bar => 'BAR' ]; sub foo { shift->[FOO] } sub bar { shift->[BAR] ||= [] } package main; my $obj = MyObject->new(foo => 'baz'); my $foo = $obj->foo; # baz my $bar = $obj->bar; # []
ARRAY-backed objects are light and fast, but obviously slightly more complicated to cope with than just stuffing key/value pairs into a HASH. The easiest way to keep track of where things live is to set up some named constants to index into the ARRAY -- you can access your indexes by name, and gain compile-time typo checking as an added bonus.
A common thing I find myself doing looks something like:
package MySimpleObject; use strict; use warnings; sub TAG () { 0 } sub BUF () { 1 } # ... sub new { my $class = shift; my %params = @_ > 1 ? @_ : %{ $_[0] }; bless [ $params{tag}, # TAG ($params{buffer} || []) # BUF # ... ], $class } sub tag { shift->[TAG] } sub buffer { shift->[BUF] } # ...
... when I'd rather be doing something more like the "SYNOPSIS".
This tiny module takes, as arguments to import, an ARRAY of pairs mapping a new() parameter name to the name of a constant. The constant represents the item's position in the object's backing ARRAY.
import
new()
If the constant's name is boolean false, the uppercased parameter name is used as the name of the constant:
use Object::ArrayType::New [ foo => '', bar => '' ]; # same as foo => 'FOO', bar => 'BAR'
If the parameter's name is boolean false, there is no construction-time parameter. The constant is installed and the appropriate position in the backing ARRAY is set to undef at construction time; this can be useful for private attributes:
undef
use Object::ArrayType::New [ foo => 'FOO', '' => 'BAR' ]; sub foo { shift->[FOO] ||= 'foo' } sub _bar { shift->[BAR] ||= [] }
An appropriate constructor is generated and installed, as well as constants that can be used within the class to index into the $self object.
$self
The generated constructor takes parameters as either a list of pairs or a single HASH. Parameters not specified at construction time are undef.
That's it; no accessors, no defaults, no type-checks, no required attributes, nothing fancy. Class::Method::Modifiers may be convenient there; the above raw Perl example could be written something like:
use Object::ArrayType::New [ tag => '', buffer => 'BUF' ]; sub tag { shift->[TAG] } sub buffer { shift->[BUF] } use Class::Method::Modifers; around new => sub { my ($orig, $class) = splice @_, 0, 2; my $self = $class->$orig(@_); $self->[BUF] = [] unless defined $self->[BUF]; $self };
if $ENV{OBJECT_ARRAYTYPE_DEBUG} is true, generated code is printed to STDERR before being evaluated.
$ENV{OBJECT_ARRAYTYPE_DEBUG}
Constants aren't currently sanity-checked ahead of time; attempting to use invalid identifiers will result in vague 'Illegal declaration ...' failures.
Jon Portnoy <avenj@cobaltirc.org>
To install Object::ArrayType::New, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Object::ArrayType::New
CPAN shell
perl -MCPAN -e shell install Object::ArrayType::New
For more information on module installation, please visit the detailed CPAN module installation guide.