#!perl -l use strict; package Base; sub package_attrs : lvalue { my $self=shift; my $caller=shift || caller or die "For use by subclasses only\n"; $self->{$caller} } sub new { my $class=shift; my $self=bless {},$class; $self->init(@_); return $self; } sub init { my $self=shift; my %params=@_; $self->package_attrs=\%params; return $self; } package Base::Sub; our @ISA=qw(Base); sub init { my $self=shift; my ($x,$y,$z)=(shift,shift,shift); $self->package_attrs={foo=>$x,bar=>$y,baz=>$z}; $self->SUPER::init(@_); return $self; } sub foo { my $self=shift; my $attrs=$self->package_attrs; return @_ ? (($attrs->{foo}=shift),$self) : $attrs->{foo} } package Base::Sub::Woofer; our @ISA=qw(Base::Sub); sub init { my $self=shift; my ($x,$y,$z)=(shift,shift,shift); $self->package_attrs={foo=>$x,bar=>$y,baz=>$z}; $self->SUPER::init(@_); return $self; } sub bar { my $self=shift; my $attrs=$self->package_attrs; return @_ ? (($attrs->{bar}=shift),$self) : $attrs->{bar} } package main; use Data::Dumper; my $obj1=Base->new(foo=>"Delicious"); my $obj2=Base::Sub->new(1,2,3,foo=>"Delicious"); my $obj3=Base::Sub::Woofer->new(10,20,30,1,2,3,foo=>"Delicious"); $obj3->package_attrs="foo"; print Dumper($obj1,$obj2,$obj3);