[KLUG Members] Perl OOP wrappers and collisions in namespace?

Mike Slack members@kalamazoolinux.org
Fri, 20 Jul 2001 14:31:20 -0700


You probably want to take a look at Damian Conway's Class::Multimethods module (from CPAN).  It is designed to have inheritance work in more flexible ways (including ones similar to how you have set things up), rather than the usual perl @ISA way (which, as you have found, is not ideal for all circumstances).  Take a look especially at Class::Multimethods::superclass. 

-- 
Mike Slack
mike@slacking.org
--
"If we knew what it was we were doing, it wouldn't
be called research, would it?" --Albert Einstein


Scott Wood (treii28@yahoo.com) wrote:
> Alrightee - any perl oop experts out there?  I have been trying to master
> polymorphism, abstraction and most specifically - inheritance.
> 
> I have a package suite that consists of - lets just say for this portion of it
> - three levels of inherited code that is sort of as follows:
> 
> defaults:                      DataDefaults.pm            (core properties)
> 
>                           /      |       |      \
> 
> data types:         Type1.pm Type2.pm Type3.pm Type4.pm    (data type specific)
> 
>                           \      |       |      /
> 
> wrapper:                      TypesWrapper.pm
> 
> 
> 
> The idea being, to:
> 1) use the defaults level to define any global properties or methods that apply
> to all data types.
> 2) use the data types level to specify type specific properties related to the
> type of data being handled.  (e.g. Text, Int, Float, Currency, etc.)
> 3) use the wrapper level to provide a single interface to all the types. (and
> only an interface)
> 
> Since the wrapper works only as an interface, I actually define the Type()
> method in the default level.  All of the data objects will have a 'Type'
> declaration after all.
> In the data types level, I then include things like Value() to store the actual
> value associated with the type (and check it for validity at the same time),
> ValueFormatted() to produce a prettified version of Value(), etc.
> 
> This all works fine as do storing parameters.  Each new object instance stores
> it's own values and works great!  So, what is the problem?  Well, to implement
> the wrapper layer, I use eval calls to point to the specific package 'new' from
> the parent level.  Something like this. (granted, I have removed error checking
> for clarity)
> 
> from TypesWrapper.pm :
> 
> -------------------- % cut here % ----------------------
> package TypesWrapper;
> 
> use TypesWrapper::Type1;
> use TypesWrapper::Type2;
> use TypesWrapper::Type3;
> use TypesWrapper::Type4;
> our @ISA = ( qw(
>                 TypesWrapper::Type1
>                 TypesWrapper::Type2
>                 TypesWrapper::Type3
>                 TypesWrapper::Type4
>                 ) );
> 
> use strict;
> 
> sub new {
>   my $proto = shift;
>   my %args   = @_;   # arguements passed via a hash including Type
>   my $caller_is_obj = ref($proto);
>   my $class = $caller_is_obj || $proto;
> 
>   # pre-declare the methods in this class
>   my %Methods = (
>                  # define any local methods - thus far I have none at this
> level
>                 );
> 
>   my $self; # initialize/declare a variable for $self
>   # sans error checking - just presume type is always going to be set properly
> 
>   my $_eval = '$self=TypesWrapper::'.$args{Type}.'->new(%args);';
>   eval($_eval);
>   bless { %{$self}, %Methods }, $class; # rebless the new class
> 
>   # CODE TO INTIALIZE VALUES WOULD GO HERE
> 
>   return $self;
> };
> 
> # OTHER CLASS METHODS WOULD GO HERE
> 
> 1;
> -------------------- % cut here % ----------------------
> 
> As I said, I did some initial testing and it presumed to work just fine.  Then
> I started doing some of the data manipulation and varification for different
> data types in Value() and different formatting in ValueFormat().  While each
> new object retains its own (sometimes adulterized) values, only the routines
> from 'Type1' in the @ISA tree are getting hauled down.
> 
> I think I somewhat understand as to why, as it is looking through the ISA tree
> for a given function, but short of writing a similar eval for every method
> inherited, can anyone suggest another means of doing this?
> 
> To summarize, I have all these Types, but I only want to call one object with a
> parameter Type => 'Type#' to get the properties associated to that specific
> one.  (and yes, some of they may have some properties that others will not have
> - not to mention identically named methods that behave completely differently)
> 
> Any suggestions or assistance is greatly appreciated.  Thanks.
> 
> Scott
> 
> __________________________________________________
> Do You Yahoo!?
> Get personalized email addresses from Yahoo! Mail
> http://personal.mail.yahoo.com/
> _______________________________________________
> Members mailing list
> Members@kalamazoolinux.org
>