ArmchairDissident has asked for the wisdom of the Perl Monks concerning the following question:

Esteemed and venerable monks, (hey, groveling never hurt!) I have a problem. I have a number of classes that work wonderfully if I copy and paste:
package foo; sub new { ... } sub someOtherFunction { ... } package bar; sub new { ... } sub someOtherFunction { ... } package baz; sub new { ... } sub someOtherFunction { ... }
But for the life of me, I can't get these classes working in a module; I can only get them working in an application using them directly (i.e. copy and paste into each perl script that needs them). I've tried everything I know, and I'm feeling strangely ignorant. I've tried putting them into a series of .pm files in a hierarchy and using
use test::foo; use test::bar; use test::baz;
Which not only seems terribly wasteful, it doesn't solve the problem. Is it possible to declare and use more than one public class in a module? If so, how on earth does one do it? In other words: How do I set up foo, bar, and baz to be classes in the same namespace??

Replies are listed 'Best First'.
Re: Multiple classes in modules
by ikegami (Patriarch) on Oct 05, 2004 at 19:00 UTC

    If the file name is MyTest.pm, just do use MyTest or BEGIN { require "MyTest.pm"; } (subbtle differences left to you to lookup). use doesn't care what packages are used inside the file. For example,
    use Bah looks for Bah.pm, and
    use Foo::Bar looks for Foo/Bar.pm,
    even if they contain packages
    Cow::Moo,
    Cow::Eat and
    Milkmaid.
    perl looks for the modules in the the paths listed in @INC. See use lib for a method to edit @INC.

      That's indeed true. I didn't know that, but tried the following, it works:
      # file: MyDir/MyTest.pm package MyDir::Foo; sub new{ my $class = shift; my $self = {}; bless $self, $class; return $self; } sub foo{ print "Foo\n"; } package MyDir::Bar; sub new{ my $class = shift; my $self = {}; bless $self, $class; return $self; } sub bar{ print "Bar\n"; } 1;
      With test code:
      use strict; use MyDir::MyTest; my $foo = MyDir::Foo->new(); $foo->foo(); my $bar = MyDir::Bar->new(); $bar->bar();
      Updated. In fact, one can simply name the package as "Foo" and "Bar" instead of "MyDir::Foo" and "MyDir::Bar". In other words, "use" is tied to the directory layout, but not to the contents of the files. Am I too general here?

        The catch is that use MyDir::MyTest; will attempt to call MyDir::MyTest::import. That can be avoided by using either
        use MyDir::MyTest ();
        or
        BEGIN { require MyDir::MyTest; }
        or
        BEGIN { require "MyDir/MyTest.pm"; }

Re: Multiple classes in modules
by chromatic (Archbishop) on Oct 05, 2004 at 19:07 UTC
    How do I set up foo, bar, and baz to be classes in the same namespace??

    That question doesn't make sense in the context of Perl. A class is just a package. A package is a namespace.

    Can you post the code that isn't working with all of the relevant output and what you expect it to do?

Re: Multiple classes in modules
by dragonchild (Archbishop) on Oct 05, 2004 at 18:57 UTC
    What errors are you seeing? My mind-reading helmet is in the shop this week.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Multiple classes in modules
by Anonymous Monk on Oct 05, 2004 at 19:27 UTC
    If you want to be able to do use test::foo, use test::bar and use test::baz then you will need the file test/foo.pm which has the following line: package test::foo