package Widget::Part; use strict; use warnings; require Carp; sub new { shift; # throw away this class. We won't use it. my %opts = (@_); # Must have a part 'type' for success. unless (defined $opts{type}) { Carp::carp("no part type provided"); return undef; } # Build and require the subclass for this type: my $class = __PACKAGE__ . "::" . $opts{type}; eval "require $class"; if ($@) { Carp::carp("Part type '$opts{type}' unknown"); return undef; } # Build the Part object template: my $self = { # name provided directly, or implicitly by type. name => $opts{name} // $opts{type}, }; # Bless into the determined subclass for this type: bless $self, $class; # Call subclass initilization code: $self->init(); return $self; } # Basic example accessor: return this part's name. sub name { my $self = shift; return $self->{name}; } 1;