anonymized user 468275 has asked for the wisdom of the Perl Monks concerning the following question:

I have a class A whose instance variable is a hash reference. One of the values is a reference to an array of hash. I want to create an additional class B whose objects are elements of this array.

I have a library directory $HOME/lib for my modules and have made a subdirectory AAA where module A lives and expect to use lib "$ENV{HOME}/lib"; (except it will be literally defined, without ENV), but that might not be right.

Because my question is: Where should these modules actually be located, how should I include them best in @INC and how should I therefore reference their methods? Let's say for simplicity we just have four methods here: both have a 'new', A has a method addB to insert B's objects into the mentioned array inside A's instance variable and B has a method 'process' that only knows about its given instance of B.

Thanks for any advice.

One world, one people

Replies are listed 'Best First'.
Re: children without inheritance
by chrestomanci (Priest) on Nov 19, 2010 at 13:44 UTC

    You are asking where in the file system the class source code should live? I guess the answer is anywhere you care to put it.

    The naming of perl classes does no imply inheritance, so if B is a sub class of A, you don't have to name them MyCompany::A and MyCompany::A::B. You can if you like, and in many places that is the coding convention, but there is no requirement to do so from the language.

    Conversely, If A and B are not related to each other through class inheritance, then neither the language, nor any coding convention I have come across says anything about how you should name the classes. You can do whatever you see fit.

    Sorry I can't provide an answer, but I don't think your question has one.

Re: children without inheritance
by locked_user sundialsvc4 (Abbot) on Nov 19, 2010 at 14:13 UTC

    I agree that your question is very hard to fathom.   Perhaps if you could explain your situation in more detail to us, you would get more-useful answers.

    I would say, though, that you really do want @INC to serve its intended purpose:   that you really don’t want to write code that is dependent upon the layout of the file-system.   You should be dealing only with package name-spaces, expecting that when you use or require one of those names, “it miraculously appears,” and you don’t care from whence it came.

    This whole design-concept smells vaguely fishy to me.   It is a familiar smell, and I have learned not to like it.   “My elvish sword has begun to glow,” and somewhere in the distance I seem to hear a familiar lament, “abandon all hope, ye who enter here ...”   I suggest that you contemplate carefully just where you are trying to go, and that you not cling too tightly to your present notions of how to get there.   As they used to say, “smoke it over, a little more.”

Re: children without inheritance
by ikegami (Patriarch) on Nov 19, 2010 at 14:36 UTC

    Module AAA::A would include a package AAA::A; directive, would be loaded using use AAA::A; and would be stored in file $private_lib/AAA/A.pm. The script or module loading AAA::A would have to know to look in $private_lib so @INC would have to be set up properly already, perhaps using use lib or env var PERL5LIB.

Re: children without inheritance
by anonymized user 468275 (Curate) on Nov 19, 2010 at 15:39 UTC
    OK I'll try to be more succinct. Imagine I have 300 projects whose classes all live in $HOME/lib. A project has two new classes A and B which are symbiotic but without any inheritance between them. Tomorrow I may have a project with ten classes like that or that may have inheritance, it doesn't matter. I want to know the most usual way (preferably CPAN-like) to locate the .pms for a given project and therefore given that syntactically to use the packages and call the methods. I ask that so I can see if the suggestion is conformant with CPAN or not. Thanks!

    One world, one people

      The point people are trying to make is that the file naming specifies nothing about the relationship between the classes.

      These file layouts are all valid:

      A.pm B.pm A.pm A/B.pm B.pm B/A.pm AB/A.pm AB/B.pm Foo/A.pm Foo/Bar/B.pm

      It's what's inside the files that determines inheritance, not the names of the files themselves.

      Include the following before you use any of your private modules:

      BEGIN { push(@INC, $ENV{'HOME'} . '/lib'); }

      So, for example:

      #!/usr/bin/perl use strict; use warnings; BEGIN { push(@INC, $ENV{'HOME'} . '/lib'); } use Foo::A; use Foo::Bar::B; my $a = Foo::A->new(); my $b = Foo::Bar::B->new();

      Succint wasn't requested--rather the opposite: More detail would be helpful.

      ...roboticus