http://www.perlmonks.org?node_id=932351

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

Hi everyone, Is possible to create a perl module with two or more classes, like java packages? Thanks for help.

Replies are listed 'Best First'.
Re: Perl Modules with 2 or more classes
by choroba (Cardinal) on Oct 19, 2011 at 10:50 UTC
    You can add more package declarations to a file, but you can only use the one that has the name corresponding to the file name (and it will load all the remaining packages in the same file).

      This is actually something I've always found frustrating about OOP. To be fair, it's not like any other language really has any better solution, and Python's answer seems to be even worse, while pretending to be better somehow.

      I'm a big fan of compilation-on-demand. So I want my callers to 'use' as little as possible. That means 'use'ing very specific subclasses. That means they must exist in unique files.

      Unique files are good for maintainability, contrary to Python credo. Files/classes that have old, old mtimes are by definition "stable". It can be trivially proven that they have not changed. Additionally, multiple files helps avoid merge conflicts for parallel team development. Split the responsibility of the developers on the team, and split the responsibility of the classes/files they are working on accordingly. Good design scales maintainability as well.

      OTOH, I'm also a big fan of ease-of-use. Why do I have to 'use DBD::blah'? I don't call anything in there... DBI does. Why doesn't DBI 'use' it for me instead? Having one core module to rule all the others is a good thing. But then you don't really know for sure what's getting brought in and when... so debugging is more complicated.

      I digress... just things worth thinking about...

      --Dave

        Why do I have to 'use DBD::blah'? I don't call anything in there... DBI does. Why doesn't DBI 'use' it for me instead?

        Huh? You don't need to use DBD::blah, just do DBI->connect('dbi:blah:FooBarDB') and it will do what you're asking for. You basically only need to use DBD modules to import extra things they might provide, like use DBD::Oracle qw/:ora_types/; for Oracle-specific data types.

        Maybe you were asking rhetorically to make a point?

Re: Perl Modules with 2 or more classes
by GrandFather (Saint) on Oct 19, 2011 at 20:54 UTC

    I frequently create modules containing several related packages/classes. Most often they are a main class and a number of helper classes, although sometimes I provide a base class and various derived classes that way too. The main class/package is the module name and the derived/helper classes are either not used outside the module, or (in the case of subclasses) are available just by virtue of using the module containing the base class.

    Note that Perl doesn't really provide 'classes', it provides packages which can generally be thought of as classes.

    True laziness is hard work
      Thank you all for the answers! # -- ribluc
Re: Perl Modules with 2 or more classes
by Anonymous Monk on Oct 19, 2011 at 10:42 UTC
    Yes. See Simple Module Tutorial, package
    package Foo; use Any::Moose; has 'x' => (is => 'rw', isa => 'Int'); has 'y' => (is => 'rw', isa => 'Int'); no Any::Moose; package Bar; use Any::Moose; has 'x' => (is => 'rw', isa => 'Int'); has 'y' => (is => 'rw', isa => 'Int'); has 'z' => (is => 'rw', isa => 'Int'); no Any::Moose;

      Or you can create classes dynamically with Class::MOP::Class and Moose::Meta::Class

      use 5.012; use warnings; use Class::MOP; for (qw(foo bar baz)) { my $class = ucfirst($_); Class::MOP::Class->create( $class => ( methods => { $_ => sub { say $class } } ) ); } Foo->foo; Bar->bar; Baz->baz;
Re: Perl Modules with 2 or more classes
by anneli (Pilgrim) on Oct 19, 2011 at 10:44 UTC

    Not as such; Perl modules are classes (if you so choose to use them that way, c.f. bless). If you need different kinds of objects, you might want to nest some of them in sub-packages. Below disclaimer fulfilled, I forgot all about Moose and/or other object systems!

    Disclaimer: my Perl OOP-fu is weak.

      Moose and/or other object systems have nothing to do with it. The relation between packages (classes) and files is purely a convention born of convenience. There's absolutely nothing stopping you from putting multiple packages into a single file or splitting a single package across multiple files while using only the core language. It messes with use (which assumes that the file name and package name will be identical) and can thoroughly confuse anyone trying to read/maintain the code in the future, but that's about it.

        Good points. Thank you!