-1

I have a module foo that has extended sub-modules bar and baz. I want bar and baz to modify the same set of hashes that are in foo.

Right now I have something like:

my $foo = new foo;
my $bar = new foo::bar( $foo );
$bar->doStuff();
$bar->printSelf();
my $baz = new foo::bar( $foo );
$baz->doOtherStuff();
$baz->printSelf();

Inside one of the sub-modules the constructor looks like:

sub new {
  my $class = shift;
  my $self  = shift;
  --stuff--
  bless $self, $class;
  return $self;
}

Please don't laugh too hard. Is there a way I can do this without passing in $foo?

Thanks for reading. :)

anonymous
  • 31
  • 4

2 Answers2

2

I prefer to share things through methods. That way, no one has to know anything about the data structures or variables names (although you do need to know the method name):

 {
 package SomeParent;

 my %hash1 = ();
 my %hash2 = ();

 sub get_hash1 { \%hash1 }
 sub get_hash2 { \%hash2 }

 sub set_hash1_value { ... }
 sub set_hash1_value { ... }
 }

Since SomeParent provides the interface to get at the private data structures, that's what you use in SomeChild:

 {
 package SomeChild;
 use parent 'SomeParent';

 sub some_method {
      my $self = shift;
      my $hash = $self->get_hash1;
      ...;
      }

 sub some_other_method {
      my $self = shift;
      $self->set_hash2_value( 'foo', 'bar' );
      }

 }
brian d foy
  • 129,424
  • 31
  • 207
  • 592
0

Your question is not very clear nor there is any code with hashes. But if you need module variables modified, you can use fully qualified name:

package Foo;        # don't use lowercase named, they are reserved for pragmas

our %hash1 = ();
our %hash2 = ();


package Foo::Bar;
use Data::Dump qw(dd);

sub do_stuff {
    $Foo::hash1{new_item} = 'thing';
}

sub do_other_stuff {
    dd \%Foo::hash1;
}


package main;

Foo::Bar->do_stuff();
Foo::Bar->do_other_stuff();

But if you need to modify instance variables, you need to have reference to this instance. I see some strategies that would work:

  • inherit from Foo, so the hashes will be in instance of Foo::Bar
  • pass reference to Foo in constructor and store it as property in Foo::Bar
  • pass Foo reference as parameter to method

Proper solution depends on what you are trying to do and how you going to use it.

bvr
  • 9,687
  • 22
  • 28