#! perl use strict; use warnings; package Widget { use Scalar::Util qw( blessed ); sub new { my ($class, $data) = @_; my $self = { Data => $data }; return bless $self, $class; } sub rebless { my ($self, $new_info) = @_; my $class = blessed $self; die unless $class eq __PACKAGE__; $self->{Info} = $new_info; if ($self->{Info} =~ /WXYZ/) { $class = 'Widget_A'; } elsif ($self->{Info} =~ /STUV/) { $class = 'Widget_B'; } else { die "Unrecognised class: $!"; } return bless $self, $class; } sub frobnicate { # my ($self) = @_; print "Implementation of frobnicate() for all Widgets\n"; } sub tweak { die "method tweak() must be overridden in child classes: $!"; } } #-------------------- package Widget_A { use parent -norequire, qw( Widget ); sub tweak { # my ($self) = @_; print "method tweak() for Widget_A objects\n"; } } #-------------------- package Widget_B { use parent -norequire, qw( Widget ); sub tweak { # my ($self) = @_; print "method tweak() for Widget_B objects\n"; } } #-------------------- # Client code #use Widget; my $setup_data = 'Setup'; my $object_1 = Widget->new($setup_data); $object_1->frobnicate(); my $new_info = 'WXYZ'; my $object_2 = $object_1->rebless($new_info); $object_2->tweak();