use strict; use warnings; # ABSTRACTION package My::Lesson; sub new{ my $class = shift; return bless { steps => [] }, $class; } sub add_step{ my $self = shift; push @{ $self->{ steps }}, @_; } # INCARNATION package My::Lesson::Example; our @ISA = ( 'My::Lesson' ); sub new{ my $class = shift; my $self = $class->SUPER::new; $self->add_step('one','two'); return $self; } # USAGE # Please note that this is only an example of usage. The real one will be done by an object of the Perl::Teacher class, like in # # $teacher->current_lesson( My::Lesson::Example->new ) # # or something similar package main; my $lesson = My::Lesson::Example->new; #### # INCARNATION package My::Lesson::Example; require Exporter; our @ISA = qw( Exporter ); our @EXPORT = qw( @steps ); my @steps = ( 'three', 'four' ); # ABSTRACTION package My::Lesson; use Module::Load 'autoload'; # or CPAN Module::Runtime sub new{ my $class = shift; my %opts = @_; # here must be some logic to load the appropriate incarnation module. # paying attention to the @steps array (?) # # autoload from Module::Load should be the right tool (not tested) # autoload $opts{lesson}; warn "autoloading $opts{lesson}"; return bless { steps => [ @steps ] }, $class; } # USAGE package main; my $lesson = My::Lesson->new( lesson => 'My::Lesson::Example' ); #### # ABSTRACTION package My::Lesson; use Module::Load 'autoload'; sub new{ my $class = shift; my %opts = @_; if ( $class->isa( 'My::Lesson' ) ){ return bless { steps => [] }, $class; } elsif ( $class->isa( 'Exporter' ) ){ # autoload $opts{lesson}; warn "autoloading $opts{lesson}"; return bless { steps => [ @steps ] }, $class; } else{ die "incarnation method not recognized for class [$class]!"; } }