in reply to Re: OO Perl and Design Issues
in thread OO Perl and Design Issues

Maybe I need to think about this deeper (in fact I am sure I do, you always do), but I didn't mean to suggest that I wanted two interfaces. When I said that the data may come from the table or it may come from input, I meant that it was arbitrary not distinct. So that, I want it to be generic such that it is one interface able to handle any kind of data. Thus, the constuctor is set to handle an inputed hash. That hash is checked against a "permitted" hash which makes sure that no extra hash values are added to the object. The permitted hash does much of what you suggest. It grabs the columns from the table which are allowable. I simply put this in a seperate private method which I figured would make it easier to maintain. I think this in part addresses Tye' +s concerns which I agree are something to be careful of. Here is my current constructor: sub new { my ($caller, $args) = @_; my %memberData; my $class = ref($caller) || $caller; # grab the fields that are allowed to be member data $memberData{'_permitted'} = &_permitted(); for (keys %$args) { if ($memberData{'_permitted'}->{$_}) { $memberData{$_} = $args->{$_}; } } $memberData{'errors'} = 0; my $self= bless { %memberData }, $class; # $self->error now contains errors, check before proceeding..... $self->_validate(); return $self; } Does this take care of those issues or am I way off base? As I said, I have made these classes before but usually much more straight-forward. This time I want to try and the class so that I have the handy OO interface with a class that takes the data as a parameter because the member data fields will be dynamic (or at least I want to be prepared if they are).

Replies are listed 'Best First'.
Re: Re: Re: OO Perl and Design Issues
by mstone (Deacon) on Jan 03, 2002 at 04:53 UTC

    I think I see what you're getting at. Personally, I'd write the constructor like so:

    package Base_class; ## new (args:hashref) : Object_ref # # create a new object, then initialize it from class-specific # defaults and/or argument values. # sub new { my $O = bless {}, shift; my $args = shift; my $defaults = $O->_defaults; ## iterate over the keys in %$defaults, because those are all ## we really care about: for $k (keys %$defaults) { $O->{ $k } = (defined $args->{$k}) ? $args->{ $k } : $defaults->{ $k }; } return ($O); } package Subclass_1; @ISA = qw( Base_class ); ## _defaults (nil) : hashref # # return a hash of default values for objects of this class # sub _defaults { ## this is basically a static variable for the class. i ## define such things at runtime, but that's just a personal ## taste. if ( ! defined $DEFAULTS ) { $DEFAULTS = { 'attr1' => 'val1', 'attr2' => 'val2', 'attr3' => 'val3', }; } return ($DEFAULTS); }

    That gives you the freedom to create as many subclasses as you want, each with its own signature of attributes. Each subclass will only accept values from its own signature, and every object will be fully initialized to its own signature by the time the ref leaves new().