rgatliff has asked for the wisdom of the Perl Monks concerning the following question:

Being relatively new to OO perl, I need help understanding how to validate data upon creation in a perl object. My object consists of a variety of attributes which have to be matched up to a standard list of values. For example: Company A provides a data file containing a list of colors Red, Maroon, and Brick. For my XML, I only support Red and wish to convert all instances of Maroon and Brick to Red. I assume the proper place to do this is upon the creaton of the object and can use a configuration file to define Maroon and Brick as the color Red, such that if I pass:
my $test -> Car->new { provider => "Provider A", color => "Maroon" };
then the module will use the Provider A configuration file and create the instance as {provider=>"ProviderA",color=>"Red"};

Am I going about this the right way, and if so, how do I define in my new method to run a validate_color upon creation of the object?

Thanks for the help....

Edit by tye

Replies are listed 'Best First'.
Re: Validation of Data in Module
by mirod (Canon) on Jun 24, 2001 at 13:41 UTC

    OK, so I went all out and used XML::Simple, XML::Twig and Inline::Files to write a solution that stores the providers data and the cars XML data, all in XML, all within the main file so you can download it easily. I really like Inline::Files, you should really try it out!

    #!/usr/bin/perl -w use strict; use XML::Twig; # of course! (but I use XML::Simple later) use Inline::Files; # I wanted to experiment with this one # I use XML files where lines don't mean much anyway # so it makes sense to treat each file as just one line undef $/; # get the cars XML into a twig my $t= new XML::Twig( ); my $cars= <DATA>; $t->parse( $cars); # now go through the list of cars foreach my $car ( $t->get_xpath( '/cars/car') ) { my $color= $car->field( 'color'); # get the color my $obj_car= Car->new( provider => "Provider A", # generate obje +ct color => $color); $obj_car->print; # print it $obj_car= Car->new( provider => "Provider B", # object with d +ifferent provider color => $color); $obj_car->print; # print it } exit; package Car; use XML::Simple; # used to load configuration files # the conversion table between original colors and provided ones, # for each provider my $equiv; # provider => { color => equiv_color # color => equiv_color } sub new { my( $proto, %args) = @_; my $class = ref($proto) || $proto; my $self = {}; my $color = $args{color}; my $provider = $args{provider}; $self->{provider} = $provider; $self->{original_color} = $color; # this will be run only once, then $equiv will be filled $equiv ||= load_config(); $self->{provided_color} = $equiv->{$provider}->{$color}; bless ($self, $class); return $self; } sub print { my $car= shift; printf "%s - %s - %s\n", $car->{provider}, $car->{provided_color}, $car->{original_ +color}; } # called once, to fill the package variable $equiv sub load_config { my $equiv; # Inline::Files reads files in the main package hence the ::APROVI +DER my $provider= <::APROVIDER>; $equiv->{'Provider A'}= equiv_color( $provider); $provider= <::BPROVIDER>; $equiv->{'Provider B'}= equiv_color( $provider); return $equiv; } # returns a hash of equivalent colors for a provider sub equiv_color { my $xml= shift; my $provider= XMLin( $xml); # you might want to use Data::Dumper or Data::Denter to figure out + # what's in $provider here my $equiv={}; my $colors= $provider->{colors}->{color}; foreach my $color (keys %$colors) { $equiv->{$color}= $colors->{$color}->{equiv}; } return $equiv; } __APROVIDER__ <config> <colors> <color name="Maroon" equiv="Red" /> <color name="Brick" equiv="Red" /> <color name="Red" equiv="Red" /> <color name="Sable" equiv="Yellow" /> <color name="Yellow" equiv="Yellow"/> </colors> <others></others> </config> __BPROVIDER__ <config> <colors> <color name="Maroon" equiv="Orange" /> <color name="Brick" equiv="Orange" /> <color name="Red" equiv="Red" /> <color name="Sable" equiv="Orange" /> <color name="Yellow" equiv="Yellow" /> </colors> <others></others> </config> __DATA__ <cars> <car><color>Brick</color><others>yarri yarri yarra</others></car> <car><color>Red</color><others>yarri yarri yarra</others></car> </cars>
      This is very helpful. Thanks for the code. For whoever is responsible for this site, I will gladly give any assitance I can provide. This site has proven invaluable to me in my learning and expanding of perl knowledge.
Re: Validation of Data in Module
by voyager (Friar) on Jun 24, 2001 at 08:48 UTC
    Not sure if I got the whole story, but how about:
    package mypackage; my $color_hash = { red => 'Red' , brick => 'Red' , maroon => 'Red , etc .... }; sub new { my ($class, %args) = @_; my $self = bless {}, $class; $self->{provider} = $args{provider}; $self->{color} = $color_hash->{lc($args{color})} || ''; return self; }