NAME Object::ArrayType::New - Inject constants & constructors for ARRAY-type objects SYNOPSIS 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; # [] DESCRIPTION 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 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. 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: 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. 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. Constants aren't currently sanity-checked ahead of time; attempting to use invalid identifiers will result in vague 'Illegal declaration ...' failures. AUTHOR Jon Portnoy