variable inheritance

Discussion in 'Perl Misc' started by Matt Garrish, Sep 12, 2006.

  1. Matt Garrish

    Matt Garrish Guest

    I'm faced with the problem of one module serving up data for 10
    different applications, where the only difference is the data being
    generated. Without going into the gory details, each year the data
    structure (the database) can change for each application and the
    applications have no relation to each other.

    For this reason, I've set up 10 separate modules each defining the same
    set of variables so that my generic class can access the configuration
    information without needing to know which application it is dealing
    with. Some of the data is the same between applications, so I keep that
    in the base class and then the subclasses override the variables that
    are specific to each of the children. As I'm sure the above must sound
    like gibberish, take for example:

    ### DataBase.pm

    package DataBase;

    use Exporter;
    @ISA = qw/Exporter/;
    @EXPORT = qw/%appInfo %someOtherConfig/;

    # this variable will get overriden by the child module
    # but declaring it here means I can use it in the
    # module and avoid problems with strictures
    # not finding the variable before the child require
    our %appInfo;

    our %someOtherConfig = (test => 1);

    ### Child1.pm

    package DataBase::Child1;

    use base 'DataBase';

    use Exporter;
    @ISA = qw/Exporter/;
    @EXPORT = qw/%appInfo/;

    our %appInfo = (table1 => 'col1, col2, col3');


    ### application

    use strict;
    use warnings;

    use DataBase;

    my $test = 1;

    if ($test == 1) {
    require DataBase::Child1;
    import DataBase::Child1;
    }

    print keys %appInfo;


    #########

    The above will print the correct 'table1' key, but my question is am I
    setting myself up for disaster if I actually try and go this route? I'm
    not saying it's the most elegant code, but since it's not a true object
    that I want but more of a configuration file is there any danger in my
    assumption that the require will properly result in the %appInfo being
    the child version.

    I currently have the data all in one big configuration file but it's
    quickly becoming unwieldy and too large for the web application it's
    designed to serve (plus causes other limitations I won't go into by
    sharing so much of the same data), so I want to isolate and import only
    as little data as necessary to get the job done.

    Matt
    Matt Garrish, Sep 12, 2006
    #1
    1. Advertising

  2. Matt Garrish

    Matt Garrish Guest

    wrote:

    > Matt Garrish wrote:
    > > I'm faced with the problem of one module serving up data for 10
    > > different applications, where the only difference is the data being
    > > generated. Without going into the gory details, each year the data
    > > structure (the database) can change for each application and the
    > > applications have no relation to each other.
    > >
    > > For this reason, I've set up 10 separate modules each defining the same
    > > set of variables so that my generic class can access the configuration
    > > information without needing to know which application it is dealing
    > > with. Some of the data is the same between applications, so I keep that
    > > in the base class and then the subclasses override the variables that
    > > are specific to each of the children. As I'm sure the above must sound
    > > like gibberish, take for example:
    > >
    > > ### DataBase.pm
    > >
    > > package DataBase;
    > >
    > > use Exporter;
    > > @ISA = qw/Exporter/;
    > > @EXPORT = qw/%appInfo %someOtherConfig/;
    > >
    > > # this variable will get overriden by the child module
    > > # but declaring it here means I can use it in the
    > > # module and avoid problems with strictures
    > > # not finding the variable before the child require
    > > our %appInfo;
    > >
    > > our %someOtherConfig = (test => 1);
    > >

    >
    >
    > I don't see how the %appInfo has in this package
    > gets over-writtten.
    >
    >
    > > ### Child1.pm
    > >
    > > package DataBase::Child1;
    > >
    > > use base 'DataBase';
    > >
    > > use Exporter;
    > > @ISA = qw/Exporter/;
    > > @EXPORT = qw/%appInfo/;
    > >
    > > our %appInfo = (table1 => 'col1, col2, col3');
    > >
    > >
    > > ### application
    > >
    > > use strict;
    > > use warnings;
    > >
    > > use DataBase;
    > >
    > > my $test = 1;
    > >
    > > if ($test == 1) {
    > > require DataBase::Child1;
    > > import DataBase::Child1;
    > > }
    > >
    > > print keys %appInfo;
    > >
    > >
    > > #########
    > >
    > > The above will print the correct 'table1' key, but my question is am I
    > > setting myself up for disaster if I actually try and go this route? I'm
    > > not saying it's the most elegant code, but since it's not a true object
    > > that I want but more of a configuration file is there any danger in my
    > > assumption that the require will properly result in the %appInfo being
    > > the child version.

    >
    >
    > Well, it's confusing to say the least. Are you expecting the %appInfo
    > in package DataBase to contain the same information as the %appInfo
    > in package main?
    >
    > With a bit of code added for debugging and introspection, you'll see
    > that they aren't the same:
    >


    > Importing into main from DataBase::Child1: %appInfo at app.pl line 10
    >
    > $VAR1 = {
    > 'table1' => 'col1, col2, col3'
    > };
    > $VAR1 = {};
    > $VAR1 = [
    > 'Exporter'
    > ];
    >
    >
    > Note that the %appInfo hash in DataBase remains empty.
    > Also note that the @ISA array in DataBase::Child1 only contains
    > exporter -- it's not a derived class of DataBase; you've wiped
    > out the inheritance by reassigning to @ISA.
    >


    Sorry, I haven't actually rewritten the code, so you're right that my
    hasty example probably doesn't make a whole lot of sense (I'm just
    thinking of ways around the problem right now, and "use vars" is
    probably the way I should be going so that I only have to export from
    the child and still have the code behave under strictures).

    The problem in a nutshell is how do I make the variable "exist" in the
    eyes of strictures but not know what it contains until the require
    happens. I was trying to come up with any trickery I could just in the
    interests of seeing what else was possible, but I think I'll just go
    back to tried and true.

    Matt
    Matt Garrish, Sep 12, 2006
    #2
    1. Advertising

  3. Matt Garrish

    Guest

    "Matt Garrish" <> wrote:
    > I'm faced with the problem of one module serving up data for 10
    > different applications, where the only difference is the data being
    > generated. Without going into the gory details, each year the data
    > structure (the database) can change for each application and the
    > applications have no relation to each other.


    If the data can change independently, the structure of the data can change
    independently, and the applications have no relation to each other, then
    why even bother trying to tie them together?

    > For this reason, I've set up 10 separate modules each defining the same
    > set of variables so that my generic class can access the configuration
    > information without needing to know which application it is dealing
    > with. Some of the data is the same between applications,


    Just by accident? Does this shared data change frequently? When it does
    change, is it highly likely to change in concert across all apps? If
    either of these are "no" then it seems like it would be better just to copy
    this data into each of 10 independent modules.

    > so I keep that
    > in the base class and then the subclasses override the variables that
    > are specific to each of the children. As I'm sure the above must sound
    > like gibberish, take for example:
    >
    > ### DataBase.pm
    >
    > package DataBase;
    >
    > use Exporter;
    > @ISA = qw/Exporter/;
    > @EXPORT = qw/%appInfo %someOtherConfig/;
    >
    > # this variable will get overriden by the child module
    > # but declaring it here means I can use it in the
    > # module


    You can use it in which module? You can't use it in *this* module,
    as it won't be initialized (other than to an empty list) in this module.
    Why would you want to use it if it contains nothing useful?

    > # and avoid problems with strictures
    > # not finding the variable before the child require


    And if you don't use it in *this* module, then strictures won't have any
    problem with it.

    ....
    > The above will print the correct 'table1' key, but my question is am I
    > setting myself up for disaster if I actually try and go this route? I'm
    > not saying it's the most elegant code, but since it's not a true object
    > that I want but more of a configuration file is there any danger in my
    > assumption that the require will properly result in the %appInfo being
    > the child version.


    That seems to be correct, in the main package (or whichever package
    executed the require). Not for other packages, however.

    > I currently have the data all in one big configuration file but it's
    > quickly becoming unwieldy and too large


    What does that mean? It is taking too long to parse? It is taxing your
    server memory? It is causing your text editor to crash when you try to
    edit it? It is taxing you mental ability to understand it all?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Sep 12, 2006
    #3
  4. Matt Garrish

    Uri Guttman Guest

    >>>>> "MG" == Matt Garrish <> writes:

    MG> The problem in a nutshell is how do I make the variable "exist" in the
    MG> eyes of strictures but not know what it contains until the require
    MG> happens. I was trying to come up with any trickery I could just in the
    MG> interests of seeing what else was possible, but I think I'll just go
    MG> back to tried and true.

    as we tell others when they do a config with tons of scalars:

    use a hash.

    then you can declare it with our %config in each of the required files
    (assuming they are all in the same name space). in each file you just
    execute a set of assignments (or a large slice assignment) to the config
    hash. you can even have a my hash in the file and assign it with a slice
    to the main config

    if you load the required files in the correct order (and some required
    files will load others) you can control the order of the assignments to
    get what you want. this is not true inheritance but good enough.

    and i recall talking to michael schwern about a module to make data
    inheritance work. i can't find it under his cpan id. but there might be
    something like it on cpan. as always i find that kind of design to be
    overkill.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Sep 12, 2006
    #4
  5. Matt Garrish

    Mumia W. Guest

    On 09/12/2006 05:56 AM, Matt Garrish wrote:
    > [ problem with inheriting class data snipped ]
    > The problem in a nutshell is how do I make the variable "exist" in the
    > eyes of strictures but not know what it contains until the require
    > happens. I was trying to come up with any trickery I could just in the
    > interests of seeing what else was possible, but I think I'll just go
    > back to tried and true.
    >
    > Matt
    >


    IIWY I would use Class::Data::Inheritable and re-write the
    application code to use the class data accessors.
    Mumia W., Sep 12, 2006
    #5
  6. Matt Garrish

    Matt Garrish Guest

    Uri Guttman wrote:

    > >>>>> "MG" == Matt Garrish <> writes:

    >
    > MG> The problem in a nutshell is how do I make the variable "exist" in the
    > MG> eyes of strictures but not know what it contains until the require
    > MG> happens. I was trying to come up with any trickery I could just in the
    > MG> interests of seeing what else was possible, but I think I'll just go
    > MG> back to tried and true.
    >
    > as we tell others when they do a config with tons of scalars:
    >
    > use a hash.
    >


    The data is currently in hashes, actually, but there are about fifteeen
    in all dealing with various other issues. It's essentially a table
    generator module that doesn't want to know anything specific about the
    tables but just render them according to the information you pass in.
    Unlike a straight database dump to html, however, it's configurable for
    external links, cross-references, footnotes, etc. All of this
    information has been abstracted out of the class and into the
    configuration file, but invariably the usefulness of the module has
    grown as so the scale of it has grown beyond its original conception.
    I'm now working at redesigning the config data to better scale with the
    application.

    Unfortunately my brain has also been reduced to mush in the process,
    and things that should seem obvious to me no longer are.

    > then you can declare it with our %config in each of the required files
    > (assuming they are all in the same name space). in each file you just
    > execute a set of assignments (or a large slice assignment) to the config
    > hash. you can even have a my hash in the file and assign it with a slice
    > to the main config
    >


    And that's what wasn't jumping out at me. For whatever reason I got it
    in my head to just declare it once in the parent so that it would be
    visible at compile time to the calling module and then "overwrite" it
    in the require. Thanks helping me screw my head back on.

    Matt
    Matt Garrish, Sep 12, 2006
    #6
  7. Matt Garrish

    Matt Garrish Guest

    wrote:

    > "Matt Garrish" <> wrote:
    > > I'm faced with the problem of one module serving up data for 10
    > > different applications, where the only difference is the data being
    > > generated. Without going into the gory details, each year the data
    > > structure (the database) can change for each application and the
    > > applications have no relation to each other.

    >
    > If the data can change independently, the structure of the data can change
    > independently, and the applications have no relation to each other, then
    > why even bother trying to tie them together?
    >


    Why not? The output is identical, only the structure and data differs,
    and even at that only to degrees. Since the final output is identical
    and only the data coming in different it would be silly to write 10
    different applications that all do the same thing. Unless you like the
    copy/paste approach to programming.

    > > For this reason, I've set up 10 separate modules each defining the same
    > > set of variables so that my generic class can access the configuration
    > > information without needing to know which application it is dealing
    > > with. Some of the data is the same between applications,

    >
    > Just by accident? Does this shared data change frequently? When it does
    > change, is it highly likely to change in concert across all apps? If
    > either of these are "no" then it seems like it would be better just to copy
    > this data into each of 10 independent modules.
    >


    Why would I partition off the data between what is general across all
    and what is specific to each if that weren't the case? I'm not inclined
    to go into ten (and growing) modules to update information that is
    shared across them all. The point is that the parent gets imported
    regardless of which child gets required later. As one way of making the
    data structure appear to be present when the code is compiled, I was
    toying with placing blank structures in the parent and overwriting them
    in the child.

    > ...
    > > The above will print the correct 'table1' key, but my question is am I
    > > setting myself up for disaster if I actually try and go this route? I'm
    > > not saying it's the most elegant code, but since it's not a true object
    > > that I want but more of a configuration file is there any danger in my
    > > assumption that the require will properly result in the %appInfo being
    > > the child version.

    >
    > That seems to be correct, in the main package (or whichever package
    > executed the require). Not for other packages, however.
    >


    I realize that, but that's not a concern. There is only one module that
    imports this configuration data, so I don't need it to be available
    anywhere else.

    > > I currently have the data all in one big configuration file but it's
    > > quickly becoming unwieldy and too large

    >
    > What does that mean? It is taking too long to parse? It is taxing your
    > server memory? It is causing your text editor to crash when you try to
    > edit it? It is taxing you mental ability to understand it all?
    >


    You do know that sarcasm is about as funny and original as going around
    telling everyone to "tell it to the hand", right? But whatever gets you
    off. If you've dealt with a program of any complexity before, you'd
    understand exactly what that means. The data wasn't ever intended or
    expected to grow at the rate it is now, so what was a manageable
    configuration file at first and designed for the scale of the project
    is now causing data conflicts. The approach to keep the file in its
    orginal state is to start nesting the data within new structures and
    rewriting all of the application code that handles it, or parse it down
    so that it appears as though no change has been made because each
    application has it's own data in its own config module (exactly as it
    was originally designed).

    Matt
    Matt Garrish, Sep 12, 2006
    #7
  8. Matt Garrish

    Guest

    "Matt Garrish" <> wrote:
    > wrote:
    >
    > > "Matt Garrish" <> wrote:
    > > > I'm faced with the problem of one module serving up data for 10
    > > > different applications, where the only difference is the data being
    > > > generated. Without going into the gory details, each year the data
    > > > structure (the database) can change for each application and the
    > > > applications have no relation to each other.

    > >
    > > If the data can change independently, the structure of the data can
    > > change independently, and the applications have no relation to each
    > > other, then why even bother trying to tie them together?
    > >

    >
    > Why not? The output is identical, only the structure and data differs,
    > and even at that only to degrees.


    The only thing that changes is the data being generated, but the data being
    generated is always identical. Well, then I give up.


    ....
    >
    > > > I currently have the data all in one big configuration file but it's
    > > > quickly becoming unwieldy and too large

    > >
    > > What does that mean? It is taking too long to parse? It is taxing
    > > your server memory? It is causing your text editor to crash when you
    > > try to edit it? It is taxing you mental ability to understand it all?
    > >

    >
    > You do know that sarcasm is about as funny and original as going around
    > telling everyone to "tell it to the hand", right? But whatever gets you
    > off. If you've dealt with a program of any complexity before, you'd


    That wasn't sarcasm, that a question with 4 proposed possibilities for
    answers. If you had dealt with programs of any complexity before[1], you'd
    know that all of them are real possibilities to encounter, and would know
    that how you fix them depends on which one is the actual problem.

    [1] Now that was sarcasm.


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Sep 12, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. maxw_cc
    Replies:
    1
    Views:
    3,120
    Martijn van Steenbergen
    Dec 21, 2003
  2. cppsks
    Replies:
    0
    Views:
    805
    cppsks
    Oct 27, 2004
  3. karthikbalaguru
    Replies:
    9
    Views:
    1,026
  4. Daniel Pitts
    Replies:
    27
    Views:
    1,875
    Mike Schilling
    Feb 27, 2008
  5. johnsonlau
    Replies:
    1
    Views:
    761
    Kai-Uwe Bux
    Jul 21, 2008
Loading...

Share This Page