I am not sure if the title is appropriate, but here is my problem -- given the following code

# In my script my $dbh = DBI->connect(); my $id = 1; my $obj = Obj->new($dbh, $id); my $foo = $obj->foo; my $bar = $obj->bar; # In a nearby package package Obj; use constant PI => 3.14; use constant G => 9.81; my %foo_cache; my %bar_cache; sub new { my ($class, $dbh, $id) = @_; my $self = bless {}, $class; $self->{dbh} = $dbh; $self->{id} = $id; return $self; } sub dbh { my $self = shift; return $self->{dbh}; } sub id { my $self = shift; return $self->{id}; } sub foo { my $self = shift; my $id = $self->id; my $dbh = $self->dbh; unless ($self->{foo}) { # check if foo is in cache if (exists $foo_cache{$id}) { # return from cache $self->{foo} = $foo_cache{$id}; } else { $foo_cache{$id} = PI * query_foo_from_db_using($dbh, $id); $self->{foo} = $foo_cache{$id}; } } return $self->{foo}; } sub bar { my $self = shift; my $id = $self->id; my $dbh = $self->dbh; unless ($self->{bar}) { # check if bar is in cache if (exists $bar_cache{$id}) { # return from cache $self->{bar} = $bar_cache{$id}; } else { $bar_cache{$id} = G * query_bar_from_db_using($dbh, $id); $self->{bar} = $bar_cache{$id}; } } return $self->{bar}; } 1;

I want to convert the package code above to something like

package Obj; use constant PI => 3.14; use constant G => 9.81; my %foo_cache; my %bar_cache; use parent ('Obj::Foo', 'Obj::Bar'); sub new { my ($class, $dbh, $id) = @_; my $self = bless {}, $class; $self->{dbh} = $dbh; $self->{id} = $id; return $self; } sub dbh { my $self = shift; return $self->{dbh}; } sub id { my $self = shift; return $self->{id}; } 1; ############### package Obj::Foo; sub foo { my $self = shift; my $id = $self->id; my $dbh = $self->dbh; unless ($self->{foo}) { # check if foo is in cache if (exists $Obj::foo_cache{$id}) { # return from cache $self->{foo} = $Obj::foo_cache{$id}; } else { $Obj::foo_cache{$id} = Obj::PI * query_foo_from_db_using($dbh, $ +id); $self->{foo} = $Obj::foo_cache{$id}; } } return $self->{foo}; } 1;

Update: The following line $self->{foo} = $Obj::foo_cache{$id}; above doesn't seem to work. How do I access a class variable from Obj.pm from within Obj::Foo.pm? Or, what is a better way to accomplish what I am trying to do?

############### package Obj::Bar; sub bar { my $self = shift; my $id = $self->id; my $dbh = $self->dbh; unless ($self->{bar}) { # check if bar is in cache if (exists $Obj::bar_cache{$id}) { # return from cache $self->{bar} = $Obj::bar_cache{$id}; } else { $Obj::bar_cache{$id} = Obj::G * query_bar_from_db_using($dbh, $i +d); $self->{bar} = $Obj::bar_cache{$id}; } } return $self->{bar}; } 1;

Besides the fact that making Obj inherit from Foo and Bar doesn't seem right (after all, Obj is not a type of Foo or Bar; instead, Foo and Bar are parts of Obj) it does work. My question to you before I embark on the above design -- anything wrong with this? Do I have to be aware of any gotchas?

--

when small people start casting long shadows, it is time to go to bed

In reply to Designing an OO program with multiple inherited classes by punkish

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.