# 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?
In reply to Designing an OO program with multiple inherited classes by punkish
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |