in reply to Multiple Packages in a Module?

A matching between the identifiers following package and use is not enforced by Perl, albeit it is a convention which is useful in most cases.

You can easily have many files containing package Foo; and, later in the same file, package Foo::Bar. In your example, you would then say use test_v1; and have all symbols in both packages available. You need to understand, however, that if you also use test_v2; in the same program and if this file also defines stuff in the Foo or Foo::Bar namespaces, then these definitions can overwrite each other (triggering warnings as they do). Here's an example of two different implementations of a Foo::Bar class:
# File test_v1.pm use strict; use warnings; package Foo; sub new { my $class = shift; bless { version => 1 }, $class; } sub version { my $self = shift; return $self->{version}; } package Foo::Bar; use parent -norequire, 'Foo'; 1;
# File test_v2.pm use strict; use warnings; package Foo; sub new { my $class = shift; bless { version => 2 }, $class; } sub version { my $self = shift; return $self->{version}; } package Foo::Bar; use parent -norequire, 'Foo'; 1;
...you can then use either of them:
  1. perl -Mtest_v1 -E "say Foo::Bar->new->version" # prints 1
  2. perl -Mtest_v2 -E "say Foo::Bar->new->version" # prints 2

Replies are listed 'Best First'.
Re^2: Multiple Packages in a Module?
by AnomalousMonk (Archbishop) on Jun 25, 2018 at 17:59 UTC

    Anonymous Monk:   Note also that in a file containing multiple package namespaces, a block structure can be very useful to achieve complete lexical isolation within each package:
        package Foo { my $private; ...; ... }  # perl version 5.14+
        package Bar { my $private; ...; ... }
    or (note required semicolon after package statement)
        { package Foo;  my $private; ...; ... }  # pre-5.14 perl
        { package Bar;  my $private; ...; ... }
    (The pre-5.14 scoping will, of course, continue to work with version 5.14+.) And definitely make use of the life-simplifying parent module!

    Update: And in any version of Perl 5, this scoping can be used to implement absolutely private package/class functions/methods:

    package Foo { ... my @stuff = ( ... ); # initialized upon inclusion ... my $private_function = sub { ... }; ... my $private_class_method = sub { my $class = shift; ...; }; my $private_object_method = sub { my $obj_ref = shift; ...; }; ... $private_function->(@stuff); ... $class_name->$private_class_method(...); $object_reference->$private_object_method(...); ... }
    (This assumes that all these separate packages are contained in a standard .pm module that is use-ed or require-ed in the, well, usual way so that phasing problems are eliminated — or at least minimized.) The naming is a bit misleading in that both the  $private_class_method and  $private_object_method methods can be invoked with either a class name or an object reference, although what you do with the class name/object reference therein is another story! But they're still private.

    All this, it must be said, starts to sound like a real OO system, of which there are many thorough-going implementations in CPAN.


    Give a man a fish:  <%-{-{-{-<

Re^2: Multiple Packages in a Module?
by tobyink (Canon) on Jun 25, 2018 at 19:41 UTC

    "use Foo; instructs Perl to look in its list of module directories for a file called Foo.pm."

    It does a bit more than that. It also runs Foo->import() after loading Foo.pm.

      haj: "use Foo; instructs Perl to look in its list of module directories for a file called Foo.pm."
      tobyink: It does a bit more than that. It also runs Foo->import() after loading Foo.pm.
      That's correct, and I am guilty for oversimplification with regard to that. I am sorry for not having written a more detailed description which could have also clarified a few other inaccuracies which have surfaced in this thread. Sigh. I made some assumptions about the intentions in the original post, but obviously other monks have made other assumptions.