NAME

Class::Clone - Create a subclass or a copy of a class on-the-fly

SYNOPSIS

# Another::Package gets its methods from Some::Package,
# but to SUPER:: in Another::Pacakge will go to Another::Package::Super,
package Some::Package::Super;
sub method {
  my $class = shift;
  return "method";
}

package Some::Package;
sub method {
  my $class = shift;
  return $class->SUPER::method . "ical";
}

package Another::Package::Super;
sub method {
  return "naut";
}

package main;
use Class::Clone qw(class_clone);
use Test::More qw(no_plan);

@Some::Package::ISA = qw(Some::Package::Super);
class_clone('Some::Package', 'Another::Package');

@Another::Package::ISA = qw(Another::Package::Super);

is(
  Another::Package->method,
  'nautical',
  "Another::Package's namespace is completely independant of Some::Package"
);

DESCRIPTION

Class::Clone makes an exact clone of an existing class, whose variables and subroutines are not in any way tied back to the existing class or it's parent classes. If you change any variables in the clone, the changes don't affect the parent class. When a cloned subroutine has a call like

$self->SUPER::do_something()

the clone class's parents are traversed. This module is called Class::Clone because this behaviour lends itself well to creating certain types of factory / polymorph classes.

(This is in contrast to importing variable or subroutine references from other packages, typically via 'Exporter'. When you do that, your copy is the original copy, so changing inherited variables affects your parent packages, and SUPER:: will call the original parent's parent, even if you change your @ISA)

USAGE

Two functions are available for export from Class::Clone:

class_clone($from, $to[, %what])

Copy all of the symbols in package $from into package $to. If a symbol already exists in $to, it is not overwritten.

%what is optional; if it is not specified, arrays, hashes, scalars, and code are cloned into $to. If it is specified, the keys specify what to copy:

ARRAY
HASH
SCALAR
CODE

The values specify how to copy that symbol table:

clone

Make an exact duplicate in $to.

If this is a subroutine (CODE), an exact duplicate will only be made if the subroutine belongs to the package in $from, unless $from's subroutine is an import itself, or comes from XS code. In those cases, the subroutine will be imported into $to.

import

Import the reference into $to.

If a false value is specified (or the key is not specified at all), no copy is done.

class_subclass($from, $to[, %what])

Generate package $to as a pure subclass of $from. If %what is not specified, no cloning is done. If it is specified, it should be in the same format as %what in class_clone.

class_clone_code($from, $to[, %what])

class_clone creates it's subclass inside an eval(). class_clone_code returns an array containing the code that would be run in this eval() without executing it. You may want to use this method in a factory scenario where you want to add some of your own methods into the cloned class.

HOW SUBROUTINES ARE COPIED

When a subroutine is cloned, it is deparsed (with B::Deparse), then eval()'ed into the destination package. This is slow and potentially troublesome, but in most cases it does work and the destination subroutine's SUPER:: will be based off of the destination package. Also, global variables mentioned in the subroutine will refer to globals in the destination package, not the source. Watch out for this; in order for the cloned subroutine to work, you will have to clone, import, or specify all of those variables as well.

BUGS

This is highly experimental and may not work the way you want or the way I want.

Some subroutines may not be copyable.

The fact that they are deparsed and then re-eval()ed is problematic at best. Problems with the deparsing or global variables might make a sub uncopyable. I'm concerned that FATAL warnings might cause problems in some cases but I haven't run into this yet.

The copying of subroutines is extremely inefficient.

There might be some better way like directly copying the bytecode, but I haven't figured that out yet.

There's currently no way to pick what variables to clone or reference.
Ancestor checks are done for subs, but not variables.

When you ask to clone a subroutine, it is only cloned if the subroutine actually lives in that package; if it was imported from elsewhere, you get an import as well. It would be useful to have the same behaviour for the other data types.

SEE ALSO

Exporter, Clone, SUPER, Symbol::Table

AUTHOR

Tyler "Crackerjack" MacDonald <japh@crackerjack.net>

LICENSE

Copyright 2005 Tyler MacDonald. This is free software; you may redistribute it under the same terms as perl itself.