B
bigmattstud
I'm trying to load multiple classes with the same name from different
directories in order to implement a pluggable deployment system. I
have managed to get the classes to be redefined by playing with the
global symbol table, and it seems to be behaving the way I want except
for the definition of @ISA. Here's some sample code:
Here's the driving script:
# Create a class and instantiate it from the first directory
print "Constructing MyMod from D:/Data/Perl/Module1\n" ;
push @INC,'D:/Data/Perl/Module1' ;
require MyMod ;
print "MyMod is a ",join(',',@MyMod::ISA),"\n" ;
$build = MyMod->new() ;
print "\n" ;
# Clean out the previous definition of MyMod by deleting the entries
from the INC hash and the global symbol
# table
delete $INC{"MyMod.pm"} ;
delete $main::{'MyMod::'} ;
pop @INC ;
# Create a class and instantiate it from the second directory
print "Constructing MyMod from D:/Data/Perl/Module2\n" ;
push @INC,"D:/Data/Perl/Module2" ;
require MyMod ;
print "MyMod is a ",join(',',@MyMod::ISA),"\n" ;
$build = MyMod->new() ;
Here's the definition of MyMod from the D:/Data/Perl/Module1 directory
package MyMod;
use strict;
use base qw(BaseBuild1) ;
sub new {
my $class = shift ;
my $self = $class->SUPER::new();
return $self;
}
1;
and the base class for this is:
package BaseBuild1;
use strict;
sub new {
print "Inside BaseBuild1 constructor\n" ;
my $class = shift;
my $self = bless {}, $class;
return $self;
}
1;
Here's the definition of MyMod from the D:/Data/Perl/Module2 directory
package MyMod;
use strict;
use base qw(BaseBuild2) ;
sub new {
my $class = shift ;
my $self = $class->SUPER::new();
return $self;
}
1;
and here's the base class
package BaseBuild2;
use strict;
sub new {
print "Inside BaseBuild2 constructor\n" ;
my $class = shift;
my $self = bless {}, $class;
return $self;
}
1;
This is the output:
Constructing MyMod from D:/Data/Perl/Module1
MyMod is a BaseBuild1
Inside BaseBuild1 constructor
Constructing MyMod from D:/Data/Perl/Module2
MyMod is a BaseBuild1
Inside BaseBuild2 constructor
So the behaviour seems correct (in that it's doing what I want), but
Perl seems to be stubbornly holding onto the definition of MyMod as a
BaseBuild1 (even though the call to SUPER::new goes to the correct
constructor). So my questions are:
* Does this matter at all ?
* Is there any way to fix it ?
* Is there a better way to do what I want to do ?
directories in order to implement a pluggable deployment system. I
have managed to get the classes to be redefined by playing with the
global symbol table, and it seems to be behaving the way I want except
for the definition of @ISA. Here's some sample code:
Here's the driving script:
# Create a class and instantiate it from the first directory
print "Constructing MyMod from D:/Data/Perl/Module1\n" ;
push @INC,'D:/Data/Perl/Module1' ;
require MyMod ;
print "MyMod is a ",join(',',@MyMod::ISA),"\n" ;
$build = MyMod->new() ;
print "\n" ;
# Clean out the previous definition of MyMod by deleting the entries
from the INC hash and the global symbol
# table
delete $INC{"MyMod.pm"} ;
delete $main::{'MyMod::'} ;
pop @INC ;
# Create a class and instantiate it from the second directory
print "Constructing MyMod from D:/Data/Perl/Module2\n" ;
push @INC,"D:/Data/Perl/Module2" ;
require MyMod ;
print "MyMod is a ",join(',',@MyMod::ISA),"\n" ;
$build = MyMod->new() ;
Here's the definition of MyMod from the D:/Data/Perl/Module1 directory
package MyMod;
use strict;
use base qw(BaseBuild1) ;
sub new {
my $class = shift ;
my $self = $class->SUPER::new();
return $self;
}
1;
and the base class for this is:
package BaseBuild1;
use strict;
sub new {
print "Inside BaseBuild1 constructor\n" ;
my $class = shift;
my $self = bless {}, $class;
return $self;
}
1;
Here's the definition of MyMod from the D:/Data/Perl/Module2 directory
package MyMod;
use strict;
use base qw(BaseBuild2) ;
sub new {
my $class = shift ;
my $self = $class->SUPER::new();
return $self;
}
1;
and here's the base class
package BaseBuild2;
use strict;
sub new {
print "Inside BaseBuild2 constructor\n" ;
my $class = shift;
my $self = bless {}, $class;
return $self;
}
1;
This is the output:
Constructing MyMod from D:/Data/Perl/Module1
MyMod is a BaseBuild1
Inside BaseBuild1 constructor
Constructing MyMod from D:/Data/Perl/Module2
MyMod is a BaseBuild1
Inside BaseBuild2 constructor
So the behaviour seems correct (in that it's doing what I want), but
Perl seems to be stubbornly holding onto the definition of MyMod as a
BaseBuild1 (even though the call to SUPER::new goes to the correct
constructor). So my questions are:
* Does this matter at all ?
* Is there any way to fix it ?
* Is there a better way to do what I want to do ?