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 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 a list of pairs mapping a "new()" parameter to the name of a constant representing the parameter's position in the backing ARRAY. If the constant's name is boolean false, the uppercased parameter name is taken 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, 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 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 'Illegal declaration ...' failures. AUTHOR Jon Portnoy