NAME
    Object::LocalVars - Outside-in objects with local aliasing of $self and
    object variables

SYNOPSIS
      package My::Object;
      use strict;
      use Object::LocalVars;

      give_methods our $self;  # this exact line is required

      our $field1 : Prop;
      our $field2 : Prop;

      sub as_string : Method { 
        return "$self has properties '$field1' and '$field2'";
      }
  
DESCRIPTION
    *This is an early development release. Documentation is incomplete and
    the API may change. Do not use for production purposes. Comments
    appreciated.*

    This module helps developers create "outside-in" objects. Properties
    (and `$self') are declared as package globals. Method calls are wrapped
    such that these globals take on a local value that is correct for the
    specific calling object and the duration of the method call. I.e.
    `$self' is locally aliased to the calling object and properties are
    locally aliased to the values of the properties for that object. The
    package globals themselves are empty and data are stored in a separate
    namespace for each package, keyed off the reference addresses of the
    objects.

    "Outside-in" objects are similar to "inside-out" objects, which store
    data in a single lexical hash closure for each property that is keyed
    off the reference addresses of the objects. Both differ from
    "traditional" Perl objects, which store data for the object within a
    blessed data structure. For both "outside-in" and "inside-out" objects,
    data is stored centrally and the blessed reference is simply a key to
    look up the right data in the central data store.

    Unlike with "inside-out" objects, the use of package variables for
    "outside-in" objects allows for the use of local symbol table
    manipulation. This allows Object::LocalVars to deliver a variety of
    features, though with some drawbacks.

  Features

    *   Provides $self automatically to methods without `my $self = shift'
        and the like

    *   Provides dynamic aliasing of properties within methods -- methods
        can access properties directly as variables without the overhead of
        calls to accessors or mutators, eliminating the overhead of these
        calls in methods

    *   Array and hash properties may be accessed via direct dereference of
        a simple variable, allowing developers to push, pop, splice, etc.
        without the usual tortured syntax to dereference an accessor call

    *   Properties no longer require accessors to provide a way to do
        compile time syntax checking under `strict'

    *   Uses attributes to mark properties and methods, but only in the
        BEGIN phase so should be mod_perl friendly (though I haven't tested
        this yet)

    *   Provides attributes for public, protected and private properties,
        class properties and methods

    *   Does not use source filtering

    *   Orthogonality -- can subclass just about any other class, regardless
        of implementation. (Also a nice feature of some "inside-out"
        implementations)

  Drawbacks

    *   Method efficiency -- wrappers around methods create extra overhead
        on method calls

    *   Minimal encapsulation -- data is hidden but still publically
        accessible, unlike approaches that use lexical closures to create
        strong encapsulation

    *   Designed for single inheritance only. Multiple inheritance may or
        may not work depending on the exact circumstances

USAGE
  Overview

    (discuss general usage, from importing through various pieces that can
    be defined)

  Declaring Object Properties

      our $prop1 : Prop;

    (Define object properties)

    Properties are declared by specifying an `our' variable with an
    appropriate attribute. There are a variety of attributes (and aliases
    for attributes) available which result in different degrees of privacy,
    different rules for creating accessors, etc.

    (Discuss aliasing)

    Object::LocalVars provides the following attributes for object
    properties:

      :Prop
      :Priv

    Either of these attributes declare a private property. Private
    properties are aliased within methods, but no accessors or mutators are
    created. This is the recommended default unless specific alternate
    functionality is needed.

      :Prot

    This attribute declares a protected property. Protected properties are
    aliased within methods, and an accessor and mutator are created.
    However, the accessor and mutator may only be called by the declaring
    package or a subclass of it.

      :Pub

    This attribute declares a public property. Public properties are aliased
    within methods, and an accessor and mutator are created that may be
    called from anywhere.

      :ReadOnly

    (Not yet implemented) This attribute declares a public property. Public
    properties are aliased within methods, and an accessor and mutator are
    created. The accessor may be called from anywhere, but the mutator may
    only be called from the declaring package or a subclass of it.

  Declaring Class Properties

      our $class1 : Class;

    Class properties work like object properties, but the same value for
    each is available for all objects (or when called as a class method).

    Object::LocalVars provides the following attributes for class
    properties:

      :Class
      :ClassPriv

    Either of these attributes declare a private class property. Private
    class properties are aliased within methods, but no accessors or
    mutators are created. This is the recommended default unless specific
    alternate functionality is needed.

      :ClassProt

    This attribute declares a protected class property. Protected class
    properties are aliased within methods, and an accessor and mutator are
    created. However, the accessor and mutator may only be called by the
    declaring package or a subclass of it.

      :ClassPub

    This attribute declares a public class property. Public class properties
    are aliased within methods, and an accessor and mutator are created that
    may be called from anywhere.

      :ReadOnly

    (Not yet implemented) This attribute declares a public class property.
    Public class properties are aliased within methods, and an accessor and
    mutator are created. The accessor may be called from anywhere, but the
    mutator may only be called from the declaring package or a subclass of
    it.

  Declaring Methods

      sub foo : Method {
        my ($arg1, $arg2) = @_;  # no need to shift $self
        # $self and all properties automatically aliased
      }

    (define methods)

    (discuss how $self and properties are made available)

    Object::LocalVars provides the following attributes for subroutines:

      :Method
      :Pub

    Either of these attributes declare a public method. Public methods may
    be called from anywhere. This is the recommended default unless specific
    alternate functionality is needed.

      :Prot

    This attribute declares a protected method. Protected methods may be
    called only from the declaring package or a subclass of it.

      :Priv

    This attribute declares a protected method. Protected methods may only
    be called only from the declaring package. Private methods should
    generally be called directly, not using method syntax -- the major
    purpose of this attribute is to provide a wrapper that prevents the
    subroutine from being called outside the declaring package. See Hints
    and Tips.

  Accessors and Mutators

      our $foo : Pub;     # :Pub create an accessor and mutator
      $obj->foo;          # returns value of foo for $obj
      $obj->set_foo($val) # sets foo to $val and returns $obj
  
    (define and describe)

  Constructors and Destructors

    (define)

    (discuss calling pattern and usage of BUILD, PREBUILD, DEMOLISH)

  Hints and Tips

    *Calling private methods on $self*

    Good style for private method calling in traditional Perl
    object-oriented programming is to call private methods directly,
    `foo($self,@args)', rather than with method lookup, `$self-'foo(@args)>.
    With Object::LocalVars, a private method should be called as
    `foo(@args)' as the local aliases for $self and the properties are
    already in place.

    *Avoiding hidden internal data*

    For some package using Object::LocalVars, e.g. `My::Package', object
    properties are stored in `My::Package::DATA', class properites are
    stored in `My::Package::CLASSDATA', and methods are stored in
    `My::Package::METHODS'. Do not access these areas directly or overwrite
    them with other global data or unexpected results are guaranteed to
    occur.

METHODS TO BE WRITTEN BY A DEVELOPER
  `PREBUILD()'

      # Example
      sub PREBUILD {
        my @args = @_;
        # filter @args in some way
        return @args;
      }

    This subroutine may be defined to filter arguments to new() before
    passing them to a superclass new(). *This must not be tagged with a
    `:Method' attribute* or equivalent as it is called before any object is
    available. The primary purpose of this subroutine is to strip out any
    arguments that would cause the superclass constructor to die and/or to
    add any default arguments that should always be passed to the superclass
    constructor.

  `BUILD()'

      # Example
      # Assuming our $count : Class;
      sub BUILD : Method {
        my %init = @_;
        $prop1 = $init{prop1};
        $count++;
      }

    This method may be defined to initialize the object after it is created.
    If available, it is called at the end of the constructor. The `@_' array
    contains the original array passed to `new()' -- regardless of any
    filtering by `PREBUILD()'.

  `DEMOLISH()'

      # Example
      # Assume our $count : Class;
      sub DEMOLISH : Method {
        $count--;
      }

    This method may be defined to provide some cleanup actions when the
    object goes out of scope and is destroyed. If available, it is called at
    the start of the destructor (i.e `DESTROY').

METHODS AUTOMATICALLY EXPORTED
    These methods will be automatically exported for use. This export can be
    prevented by passing the method name preceded by an "!" in a list after
    the call to "use Object::LocalVars". E.g.:

      use Object::LocalVars qw( !new );

    This is generally not needed or recommended, but is available should
    developers need some very customized behavior in `new()' or `DESTROY()'
    that can't be achieved with `BUILD()' and `DEMOLISH()'.

  `give_methods()'

      give_methods our $self;

    Installs wrappers around all subroutines tagged as methods. This
    function (and the declaration of `our $self') *must* be used in all
    classes built with Object::LocalVars.

  `new()'

    The constructor. This is not used within Object::LocalVars directly but
    is exported automatically when Object::LocalVars is imported. `new()'
    calls `PREBUILD' (if it exists), blesses a new object either from a
    superclass (if one exists) or from scratch, and calls `BUILD' (if it
    exists). Classes built with Object::LocalVars have this available by
    default and generally do not need their own constructor.

  `DESTROY()'

    A destructor. This is not used within Object::LocalVars directly but is
    exported automatically when Object::LocalVars is imported. `DESTROY()'
    calls `DEMOLISH()' (if it exists) and reblesses the object into the
    first package in @ISA that can DESTROY (if any) so that destruction
    chaining will happen automatically.

  `caller()'

    This subroutine is exported automatically and emulates the built-in
    `caller()' with the exception that if the caller is Object::LocalVars
    (i.e. from the wrapper functions), it will continue to look up the
    caller stack until the first non-Object::LocalVars package is found.

BENCHMARKING
    Forthcoming. In short, faster than traditional approaches if ratio of
    property access within methods is high relative to number of method
    calls. Slower than traditional approaches if there are many method calls
    that individually do little property access.

SEE ALSO
    These other modules provide similiar functionality and inspired this
    one.

    *   Class::Std -- framework for inside-out objects; supports
        multiple-inheritance

    *   Lexical::Attributes -- inside-out objects; provides $self and other
        syntactic sugar via source filtering

    *   Spiffy -- a "magic foundation class" for object-oriented programming
        with lots of syntactic tricks using via source filtering

INSTALLATION
    The following commands will build, test, and install this module:

     perl Build.PL
     perl Build
     perl Build test
     perl Build install

BUGS
    Please report bugs using the CPAN Request Tracker at
    http://rt.cpan.org/NoAuth/Bugs.html?Dist=/home/david/projects/Object-Loc
    al

AUTHOR
    David A Golden (DAGOLDEN)

    dagolden@cpan.org

    http://dagolden.com/

COPYRIGHT
    Copyright (c) 2005 by David A Golden

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

    The full text of the license can be found in the LICENSE file included
    with this module.

