Michael Fowler <[EMAIL PROTECTED]> replies:
> Exporting is usually a bad idea when dealing with classes, it breaks
> encapsulation. You should probably setup a class method for this.
>
> That being said, you can export variables just like you export any other
> data type, with Exporter; perldoc Exporter or
> http://www.perldoc.com/perl5.6/lib/Exporter.html.
I don't really want to export the variables; I'm not modifying them in
the parent package, just copying and expanding them in the inheriting
package.
Here's what I'm really trying to do. I have a set of packages that
closely inherit from a base class. The base class and all subclasses
have some common attributes; the subclasses may add more attributes to
this set. Some attributes may be modified in certain ways and some
may not be modified. As such, I'm using separate accessor methods
get() and set() for setting the attributes, as in:
$attribute_value = $object->get('attribute_name');
$object->set('attribute_name', $attribute_value);
The 'set' method needs to know what are legal attributes and what are
legal values for a given attribute. I'm using a hash of attribute
names and regexes to define what are legal values for the allowed
attributes:
# Object attributes are changeable only if their values match the regexes
%Attributes = (
# Immutable attributes have regexp undefined
'id' => undef,
'creator' => undef,
'creation_time' => undef,
# Mutable attributes have regexp specified
'name' => '^.{1,30}$',
'description' => '^.{0,255}$',
.....
);
The 'set' method then uses this hash to verify the names and values of
attributes are acceptable before setting them. The simplified code
looks something like:
sub set {
# $self->set($name, $value);
# Get parameters and initialize variables
my ($self, $name, $value) = @_;
# Check attribute
die "Invalid attribute $name provided"
unless exists $Attributes{$name};
die "Cannot change attribute $name"
unless defined $Attributes{$name};
die "The provided value for attribute $name is not acceptable"
unless ($value =~ /$Attributes{$name}/);
.....
# Set attribute
$self->{$name} = $value;
}
(The real code is more complicated since it allows setting multiple
attributes at once.)
The package inheriting from this parent class might add more attributes:
# La/De/Da/MyPackage.pm
package La::De::Da::MyPackage
.....
use base qw( La::De::Da::MyBase ); # Takes care of @ISA and %FIELDS.
use vars qw( %Attributes ); # But also need to extend %Attributes.
%Attributes = (
# MyPackage inherits attributes from MyBase
%La::De::Da::MyBase::Attributes,
# Mutable attributes have regexp specified
'color' => '^(red|green|blue)$',
'size => '^(small|medium|large)$',
'price' => '^\$\d+\.\d\d$',
);
Another package might define different additional attributes. For a
'MyPackage' object:
my $object = La::De::Da::MyPackage->new();
$object->set('name', 'Pickle'); # OK
$object->set('description', 'dill'); # OK
$object->set('color', 'green'); # OK
$object->set('size', 'giant'); # dies, since not an acceptable value
$object->set('weight', 'heavy'); # dies, since not an acceptable name
$object->set('id', 50); # dies, since id is unchangeable
This has the advantage of having a single 'set' method in the parent
package that is smart enough to do the necessary error validation for
all inheriting packages, instead of having a separate specialized
'set' method for each package. This is a real savings since I have a
large number of inheriting packages.
I have not been able to find a perl module that would allow this sort
of inheritance and data validation; does anyone know of one that does
this? Or can anyone suggest a better way of doing what I want?
+ Richard J. Barbalace