NAME

Class::SubclassDeep - Perl extension for subclassing "out-of-reach" classes

SYNOPSIS

  use Class::SubclassDeep;
  subclass( class1 => "sub_class1",  class2 => "sub_class2( constructor)";
  my $object= top_class->new;

top_class originally creates sub-objects in the class1 and class2 packages (using new for class1 and constructor for class2).

After the call to subclass the sub-objects will be now created as sub_class1 and sub_class2.

The constructor does not need to be present in the new classes.

DESCRIPTION

This module can be used to change the classes of objects generated by object factories:

If you are using an existing module with an OO interface, then you can subclass this object. If this object itself is an object factory, ie if it generates other objects, in other classes, it might be difficult to subclass these objects, unless the original author has put the appropriate hooks in the code.

Class::SubclassDeep lets you solve this by specifying classes to use instead of the hard-coded ones.

Here is an exemple, with XML::DOM (I do not advise you to use XML::DOM BTW, but that's not the point here, and XML::DOM is one of those real tricky modules where using Class::Subclass::Deep is just the beginning of the story...)

  #!/usr/bin/perl -w
  use strict; 

  use Class::SubclassDeep;
  use XML::DOM;

  my $doc=q{<doc><elt>an element</elt><no_id>element not to id</no_id></doc>};
  my $parser = new XML::DOM::Parser;
  # here is where the magic happens: instead of calling XML::DOM::Element->new
  # XML::DOM will now call MyElement->new
  subclass( 'XML::DOM::Element' => "MyElement"); 
  my $dom = $parser->parse ( $doc);
  print "DOM modified by Class::SubclassDeep:  ", $dom->toString;
  
  package MyElement;

  # we really want to subclass XML::DOM::Element, not to replace it
  use base 'XML::DOM::Element'; 
  my $i;

  sub new
    { shift @_;
      # MyElement->SUPER is XML::DOM::Element
      my $elt= MyElement->SUPER::new( @_);
      if( $elt->getTagName eq 'elt') { $elt->setAttribute( id => "id" . ++$i); }
      return $elt;
    }

Note that if the class to subclass has several potential constructors (XML::DOM for example has parse and parsefile), you can put them all, space separated:

    subclass( 'XML::DOM::Parser'    =>'XML::DOM::XPath::Parser (parse parsefile)');
                

EXPORT

  subclass

BUGS

  Considering how much you can do with Perl's OO system, I doubt I am covering all
        cases.

  The test suite covers most static (no changing the ISA after the compilation phase)   
        cases, but the modules works also in some funkier cases. It needs to be better tested,
        but I lack the imagination to write some real tricky test cases.
        

SEE ALSO

AUTHOR

Michel Rodriguez, <mirod@cpan.org<gt>

COPYRIGHT AND LICENSE

Copyright 2003 by Michel Rodriguez

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