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 <avenj@cobaltirc.org>

