views:

290

answers:

4

I'm pretty sure that I read somewhere that it's possible, but there are a few gotchas that you need to be aware of. Unfortunately, I can't find the tutorial or page that described what you need to do. I looked through the Perl tutorials, and didn't find the one that I remember reading. Could someone point me to a page or document that describes how to put multiple packages into a single .pm file?

+9  A: 

You simply start off the new package with another package statement:

package PackageOne;

# ...... code

package PackageTwo;

# .... more code

Problems with this approach

ennuikiller
I'm pretty sure in the article that I read, there were a few other things that you had to do or problems that might appear with scoping.
Thomas Owens
of course there will be scoping problems and thats why its not recommended, See the link I added.
ennuikiller
You can only `use` a package with a name that corresponds to the filename, and you can only (easily) `use` a file that contains a package corresponding to its name. Other than that and the fact that file-scoped lexicals will "leak" into the next package (avoidable by adding braces) there isn't a lot to know.
hobbs
+4  A: 

How to do it: just issue multiple package instructions.

Gotchas I can think of: my-variables aren't package-localized, so they're shared anyway. Before you issue any, you're in package main by default.

JB
+5  A: 

In general, it is better to stick with the one package per file rule. What are you trying to achieve?

#!/usr/bin/perl

package My::A;
use strict; use warnings;

sub new { my $class = shift; bless \$class => $class }

package My::B;

use base 'My::A';
use strict; use warnings;

sub whoami { ${$_[0]} }

package My::C;

use base 'My::B';
use strict; use warnings;

package main;
use strict; use warnings;

my $x = My::B->new;
my $y = My::C->new;

print $_->whoami,"\n" for $x, $y;
Sinan Ünür
I had some classes (packages) that are just helpers for another package, to make things cleaner. Because they were only used in one place, I wanted them in that file.
Thomas Owens
@Thomas: that's the normal reason for mixing packages in one file. It's often done in CPAN distributions (if you're in the habit of reading the source for your installed modules you can pick up a few interesting tricks) :D
Ether
+7  A: 

This is how I normally do it:

use strict;
use warnings;
use 5.010;

{
    package A;
    sub new   { my $class = shift; bless \$class => $class }
    sub hello { say 'hello from A' }
}

{
    package B;
    use Data::Dumper;
    sub new   { my $class = shift; bless { @_ } => $class }
    sub hello { say 'Hello from B + ' . shift->dump       }
    sub dump  { Dumper $_[0] }
}

$_->hello for A->new, B->new( foo => 'bar' );

/I3az/

draegtun