NAME
    Class::Translucent - A base class for translucency

SYNOPSIS
        package My::Class;
        BEGIN {
            use Class::Translucent  ({
                name    => 'sparrow',
                item2   => 'else',
                attr    => { one => 'two', two => 'three', three => 'one' },
                events  => [ 'buy', 'grow', 'sell', 'eat', 'sleep' ],
            });

            @MyClass::ISA = qw{Class::Translucent};
        }

        sub new {
            my $self = shift;

            return $self->SUPER::new( @_ );
        }

        package main;

        my $o = new My::Class;
        print $o->name;             # Prints 'sparrow'
        $o->name( 'robin' );        # Set the per-object value
        print $o->name;             # Prints 'robin'
        print My::Class->name;      # Prints 'sparrow'

EXPORTS
    Nothing by default.

REQUIRES
    the Carp manpage, the Data::Dumper manpage

    Actually, Data::Dumper is only required for debugging, so this module
    will eventually only need Carp.

DESCRIPTION
    This is an abstract base class that provides functionality for
    translucent attributes in its derivatives. A translucent attribute is an
    attribute which has a class-wide default. A class's attributes are set
    in a template, from which all class and instance method calls initially
    get/set their data. However, once an object has stored a value, it loses
    its translucency, and thereafter returns its own distinct value. For
    more information about translucency, see Tom Christiansen's excellent
    *OO Tutorial for Class Data in Perl*, which can be found at
    <http://language.perl.com/misc/perltootc.html>.

    In order for your class to usefully inherit from Class::Translucent, it
    needs to tell Class::Translucent about itself via a template. This
    template should be a hash or hash reference containing keys for all the
    translucent attributes of your class, along with default values for each
    one.

    There are several methods for defining this template. If you have class
    data that needs to be accessed before any instances of your class are
    created, you can pass the template as the argument to the 'use'
    statement, like so:

        use Class::Translucent ({ attribute => 'defaultValue' });

    You can also define a package global named the same thing as the last
    part of your package (eg., if you class is called
    `HTML::Graphics::Vector', the hash should be
    `%HTML::Graphics::Vector::Vector'). When Class::Translucent's
    constructor is called as a superclass constructor from your class (or
    one of its parent classes) and it doesn't already have a template
    registered for your class, it will look for such a hash, and if it is
    found, use it as the class's template.

    You can also pass a hash reference as the first argument (well, second
    if you're counting the method invocation argument), which will then be
    used as the class template instead.

    In any case, as soon as the template is defined, Class::Translucent
    auto-generates translucent accessor methods for the attributes you've
    specified in the template, skipping any that may already be defined.

    The constructor returns an empty hashref blessed into the calling class.

    *TODO: More docs*

AUTHOR / PERSON TO BLAME
    Michael Granger <ged@FaerieMUD.org> based on ideas from *Tom's OO
    Tutorial for Class Data in Perl* (the perltootc manpage) by Tom
    Christiansen.

    Copyright (c) 1999, 2000, The FaerieMUD Consortium. All rights reserved.

    This module is free software. You may use, modify, and/or redistribute
    this software under the terms of the Perl Artistic License. (See
    http://language.perl.com/misc/Artistic.html)

TO DO
    *   Do template interpolation in the method template accessor methods
        instead of in the code generation itself. This would mean that
        subclassing would not obligate one to returning templates.

    *   Add per-class translucent data so that derivative class B's
        attributes are inherited from superclass A, but remain distinct for
        each class. Can probably accomplish this by iterating over
        @{"${class}::ISA"}, and fetching the parent class's hash and merging
        it with our own.

    *   Package-qualify object data members ala Damian Conway's
        `Tie::SecureHash'.

    *   Better documentation

    *   Better test suite (or any test suite?)

BUGS
    Unintuitive translucency with complex datatypes
        Operations other than a simple set() are ambiguous for complex
        datatypes. For example, `push' adds an element to an array -- so if
        an array attribute is translucent, should `pushAttribute()' called
        as an object method push the given value onto a new empty array, or
        should it make a copy of the class data first, and push the new
        element onto it?

        THe copy-on-write behaviour is the current behaviour, but will need
        some rigorous testing to make sure it conforms to Perl's
        do-what-I-mean.

    Cluttered BEGIN blocks
        In order for class methods to be callable immediately after the `use
        Class::Translucent', the `import()' function must do the method
        generation. This requires that the class template be mangled into
        the argument to `use', which is perhaps ugly and unintuitive to
        some. I can't see any way around it, though, as it has to occur in a
        BEGIN block in order to guarantee that the generated methods exist
        before the constructor is called. Otherwise, setting class-wide data
        must wait until the first instance is created.

    "Subroutine '*sub*' redefined..." warnings with overridden methods
        Accessor methods for translucent attributes are generated at load
        time, and overriding subs are defined after that. This can cause
        warnings to be issued when the methods are encountered in the
        derived class. This problem doesn't exist when the methods are
        created during the call to the constructor, as the method-generation
        code won't clobber a method which is already defined, but then you
        have to guarantee that no method will be called as a class method
        before the first object is constructed. You could resort to calling
        the constructor from within the package itself, but ACK! =:) Things
        will still work as is, but spurious warnings can be confusing for
        those who don't RTFM.

        You can also cause the warnings to disappear by prototyping the
        methods you wish to override before the `use Class::Translucent'
        call, but that's unintuitive.

    Reload problems
        When redefining a class during a reload, there is no current
        mechanism for re-generating the accessor methods. There should be
        some method that can be called which will clear at least the
        `%Classes' hash in the closure so a class's template can be
        reloaded. Perhaps some mechanism for clobbering existing accessors
        would also be desirable.

        Another related problem -- do Perl internals care if a method gets
        clobbered? Does Perl do caching of method lookups, and, if so, what
        will happen if the cached method is undefined during the life of the
        program? Randal Schwartz suggests modifying the @ISA, which will
        cause cached methods to be discarded, but I haven't yet tested this.

GLOBALS
  Configuration Globals

    *%AccessCheck*
        Method generation templates for the access-check part of each
        method. Attributes which are prefixed with a single underscore
        ('`_'') are considered 'protected', and the accessor methods
        generated for it may only be called from within the defining class
        or one of its derivatives. Attributes which are prefixed with two or
        more underscores are considered 'private', and may only be accessed
        from within the defining class itself. All other attributes are
        considered public, and may be accessed from any package.

        The code contained in these templates contain special tokens '`%%
        ATTRIBUTE %%'', and '`%% CLASS %%'', which will be replaced,
        respectively, with the attribute name and the name of the class for
        which they are being generated.

    *%AccessorCode*
        Method generation templates for the scoping part of the generated
        methods. Attributes with a leading capital are considered to be of
        class scope only, and calls to its accessors always modify and/or
        return the class data. All other attributes are considered
        translucent, and reference the class data if no specific value has
        been set for the object in which the accessor was called, or if the
        accessor method is called as a class rather than an instance method.

        The code in these templates can contain the same tokens as the
        `%AccessCheck' global, and they are subject to the same substitution
        at method-generation.

        Note that the attribute passed to later chunks of the method will
        always be a reference to the needed attribute, even if the attribute
        is already a reference. This is to make it easier later on to modify
        the attribute without knowing exactly where the thing being modified
        lives.

    *%MethodTemplates*
        Method generation templates for various datatypes, keyed by type.
        These templates are used to create the meat of the generated
        accessor methods. The code they contain will be passed a reference
        to the attribute to operate on in a scalar called `$attribute', and
        the rest of the argument list will be untouched.

        The word 'attribute' in the key is replaced in the generated method
        with the name of the attribute. For example, if you had a key named
        'bargleAttribute', an attribute called 'name' would result in a
        generated method called 'bargleName'. Leading underscores in an
        attribute name are always translated to the beginning of the method
        name, so if the attribute above was instead called '__name', then
        the generated method would be '__bargleName'. Attributes with
        leading capitalization result in leading capitalization in the
        generated method name as well. Eg., an attribute called 'Name' would
        result in a method named 'BargleName', and an attribute called
        '_Name' would generate a method called '_BargleName'.

        The methods in the 'default' key/value pair are given to every
        datatype, and can be overidden by the more specific datatype
        key/value pair. This can be used to establish some default behaviour
        for an accessor, and then override it for specific datatypes.

METHODS
    *import( $class, \%template )*
        Autogenerates methods for the calling class. This function can
        either be called automatically from a `use' statement, or can be
        called explicitly. Note that overriding one of the methods provided
        by this function may result in a 'subroutine redefined' warning, as
        they won't yet exist when `import()' is called, typically. This is
        probably harmless.

  Constructor Methods

    *new( @args )*
        Create and return a new hash reference blessed into your class. If
        accessors have not already been generated for your class, they will
        be generated from the constructor. Existing (overridden) methods
        will be preserved.

  Protected Methods

    *_buildAccessors( $class[, \%template] )*
        Build translucent data accessor methods for the specified class
        (package), using the template specified either by the optional
        second argument, or if the second argument is not passed, the
        template as defined in the class itself. This template should be
        synonymous with the last part of the package name, so that the
        template for `My::Derived::Class' will be called
        `%My::Derived::Class::Class'. This function

    *_buildMethodCode( $attributeName, $codeTemplate, $package )*
        Build code for a method specified by the attribute name, with the
        specified code template and bound for the specified package.

    *_makeMethodName( $attribute, $methodPrototype )*
        Make and return a method name for the specified attribute with the
        specified method name prototype.

  Static Methods

    *AccessCheck( $accessorType )*
        Return a method generation template for the access-check part of a
        generated method based on the accessor type specified. The type can
        be one of 'public', 'protected', or 'private'. See the configuration
        global of the same name for more information.

    *AccessorCode( $accessorType )*
        Return a method generation template for the scoping part of a
        generated method based on the accessor type specified. If the
        accessor type is 'class', a template appropriate for static methods
        is returned. If the specified type is 'instance', then a template
        appropriate for instance methods is returned. See the configuration
        global of the same name for more information.

    *MethodTemplates( $dataType )*
        Return a hashref of method generation templates for the specified
        datatype. See the documentation for the MethodTemplate configuration
        hash for more information.

