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

The Problem:
I have some Perl Modules, each of which has its own config file containing a rather complex data structure. The Modules are structured in a hierarchy and depend quite heavily on inheritance. Now I would like to use inheritance with the config values to e.g. specify a default value in one package and override it in another.

It look sort of like this:
package Parent; require ('./parent.cfg'); package Parent::Child; @ISA=('Parent'); require ('./child.cfg'); package Parent::Child2; @ISA=('Parent'); require ('./child2.cfg'); package Parent::Child::Grandchild; @ISA=('Child'); require ('./grandchild.cfg');
A config file looks like:
$config={ string=>"bla", array=>['val1','val2'], hash=>{ foo=>'bar', }, # etc, put any valid perl data structure here };

My not-so-ideal solution: I wrote a routine (called "config") that returns config value associated with the given key. If the key is not found in %config of the calling package, the next upper package is searched, following @ISA.

This works quite OK, but it is sort of very inconvient to change values in arrays or hashes. If I want to override a part of list of some sort, I have to put the new complete list in the Child-Config.

Eg:

in parent.cfg #... list=>['val1','val2','val3'], in child.cfg #... list=>['val1','val2','val3','FOO','BAR'],
This results in a lot of very similar config entries.

What I want:
I would like to do something like that:

parent.cfg: %config=( # complex data structur ) child.cfg: config_add('newval',$datastruct); config_remove('DontNeedThisHere'); config_push('array',$newval,$anotherval); # and some other data manipulation routines
the changes in child.cfg should only be visible in Parent::Child ,e.g
if you do
print scalar (@{Parent->config('array')})
it should print "26", but
print scalar (@{Parent::Child->config('array')})
should print "28".

Finally, my questions:

Replies are listed 'Best First'.
Re: OO Data Structures ?
by lachoy (Parson) on Dec 04, 2001 at 20:33 UTC

    These sorts of things are frequently found under the Class:: hierarchy. You might look specifically at Class::Data::Inheritable.

    Chris
    M-x auto-bs-mode

Re: OO Data Structures ?
by dragonchild (Archbishop) on Dec 04, 2001 at 20:57 UTC
    Another suggestion is to restructure the way you're going about this entire thing.

    What it sounds like is that when you instantiate an object, you pre-populate it with a bunch of data, possibly use data the user gives you, then returns the object.

    What about doing something like:

    sub new { my $class = shift; my %attributes = @_; $class = ref($class) || $class; # Cargo-cult! my $self = $class::SUPER->new(@_); # Finish up here. return $self; }
    If you do it right, this will allow for both attribute and value inheritance.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: OO Data Structures ?
by miyagawa (Chaplain) on Dec 04, 2001 at 20:40 UTC
Re: OO Data Structures ?
by Fletch (Bishop) on Dec 04, 2001 at 21:22 UTC

    Another approach might be to use AppConfig rather than files you directly require.

(jeffa) Re: OO Data Structures ?
by jeffa (Bishop) on Dec 04, 2001 at 21:06 UTC
    And yet even another suggestion (along the same lines as dragonchild's suggestion) is to slightly change your congif files. Instead of reading in the entire hash for $self all at once - read in only the attributes and their values, one at a time. This would allow you to easily override the attributes like so:
    package Parent; require ('./parent.cfg'); package Parent::Child; @ISA=('Parent'); require ('./parent.cfg'); require ('./child.cfg');
    But i think this is a bit wasteful - too many unecessary file reads - try Class::Data::Inheritable as mentioned above.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    F--F--F--F--F--F--F--F--
    (the triplet paradiddle)
    
Re: OO Data Structures ?
by domm (Chaplain) on Dec 06, 2001 at 02:22 UTC
    Thank you for your feedback / ideas.

    Class::Data::Inheritable might be a good candiate, although after reading it's docs I remembered I already looked at it some time ago and didn't found it usefull.

    perltootc was very interesting, and now I know at least the correct name of what I was looking for: Translucent Inheritable Class Data !