NAME

Class::Entangle - Functions to entangle an object.

DESCRIPTION

Class::Entangle is names after Quantum Entanglement, which is where 2 partacles are entangled in such a way that events occuring to one occur to the other as well, even if they are seperated by great distance.

Using Class::Entangle you can pull an 'entanglement' from a class. This entanglement contains a list of class properties, which includes subroutines, variables, and handles. This entanglement can be used to create entanglers, which in turn can be used to entangle a class.

An entangler is a new class definition that contains definitions for subroutines, variables, and handles that match another classes. When you define an entangler you tell it how you want it to entangle each type. Subroutines are defined by providing a callback routine. Variables and handers are defined using tie.

Once you have an entangler for a class you can use that class as you would your original class. If the class is an object defenition then you can use the entangle() function to create an instance of the entangler against an existing object.

Note: You probably don't want to use construction methods through the entangler class, it will return whatever the constructor for the original class returns. This will return a new instance of the original class.

SYNOPSIS

#!/usr/bin/perl
use strict;
use warnings;

use Class::Entangle;

# First define a class to entangle, as well as a Tie::Scalar class for
# handling the scalars.
{
    package MyClass;
    use strict;
    use warnings;

    sub new {
        my $class = shift;
        $class = ref $class if ref $class;
        return bless {}, $class;
    }

    sub subA {
        my $self = shift;
        my ( $in ) = @_;
        return "subA($in)";
    }

    our $scalarA = "scalar";
}

{
    package MyClass::TieScalar;
    require Tie::Scalar;
    our @ISA = qw(Tie::Scalar);

    sub TIESCALAR {
        my $class = shift;
        my ( $varname ) = @_;
        bless( { varname => $varname }, $class );
    }

    sub FETCH {
        my $self = shift;
        my $varname = $self->{ varname };

        no strict 'refs';
        return ${ "MyClass\::$varname" };
    }

    sub STORE {
        my $self = shift;
        my $varname = $self->{ varname };
        my ( $value ) = @_;

        no strict 'refs';
        return ${ "MyClass\::$varname" } = $value;
    }
}

my $one = MyClass->new;
my $entanglement = Class::Entangle::entanglement( $one );
# $entangler will contain the class name of the entangler.
my $entangler = Class::Entangle::entangler(
    CODE => sub {
        my $entangle = shift;
        my $subname = shift;
        if ( $entangle ) {
            return $entangle->{ entangled }->$subname( @_ );
        }
        else {
            return &{ "Test\::TestClass\::$subname" }->( @_ );
        }
    },
    SCALAR => 'MyClass::TieScalar',
);
$entangle = Class::Entangle::entangle(
    $entangler,
    entangled => $test,
);

# prints: 'subA(a)'
print $entangle->subA( 'a' );

# prints: 'HaHa, I am messing with $MyClass::scalarA!'
no strict 'refs';
${ "$entangler\::scalarA" } = 'HaHa, I am messing with MyClass::scalarA';
print ${ "$entangler\::scalarA" }

EXPORTED FUNCTIONS

entanglement( $object )

Only argument is the object to create an entanglement for. Returns an entanglement.

Note: Currently entanglements are simple hashes, this is subject to change, always get the entanglement returned by this function and use it directly, do not write code that treats it directly as a hash.

entangler( $entanglement, %params )

The first arguement should be an entanglement as returned by entanglement(). All additional params should be key => value pairs. All the following are acceptible:

    variation => 'default' - When you create an entangler it creates a class definition. This defenition contains the variation name you pass in here. If you don't pass in a variation 'default' is used. You can only define an entangler class against an entanglement once for each variation. If you want to have a different entangler for the same object you must provide a variation name.

    CODE => sub { ... } - Define the subroutine callback to use on all class subroutines. The first 2 parameters should always be shifted off before passing @_ to the entangled class. The first is either the entagle object if the sub was called as an object method, the entangler class if it was called as a class method, or undef if not called as a method. The second parameter is always the name of the sub that was called.

    HASH, ARRAY, SCALAR, IO => 'Tie::MyTie' - Specify the class to tie the specific variable type to. If you are writing a Tie for a specific variable you should know that the call to Tie looks like this:

    # $ref is "$entangler\::$item"
    # $tieclass is the class you passed to 'HASH =>'
    # $item is the name of the variable.
    tie( %$ref, $tieclass, $item );
entangle( $entangler, %object_params )

First param should be an entangler class as returned by entangler().

All additional parameters will be directly put into the hashref that is blessed as an object of type $entangler.

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 124:

=over without closing =back

Around line 210:

=back doesn't take any parameters, but you said =back 4