Question

I have a Perl script (foo.pl) that loads Foo.pm from the same directory using the require mechanism:

require "./Foo.pm";
...
my $foo = new Foo::Bar;

The Foo.pm adheres to the standard module format:

package Foo::Bar;
...
1;

Rather than distributing my application as two files (foo.pl and Foo.pm) I'd like to distribute only one file. More specifically I'd like to make Foo.pm part of the foo.pl script.

How do I achieve that?

The trivial approach of simply merging the two files (cat foo.pl Foo.pm > foo2.pl) does not work.

Was it helpful?

Solution

Your code did not work (although it would have been helpful to state the error message(s) that you received) because you attempted to use Foo::Bar before it had been defined. Try this:

use strict;
use warnings;
my $foo = Foo::Bar->new();
# more code...

# end code

# begin definitions
BEGIN {
    package Foo::Bar;
    use strict;
    use warnings;
    # definitions...
    1;

    package Foo::Baz;
    # more stuff, if you need to define another class
}

Additions:

OTHER TIPS

If you're interested in packing up your Perl script into a binary with all the modules it depends upon included, you can use PAR Packager:

pp -o binary_name foo.pl

A file can contain multiple packages. Put your class first, followed by the main script:

package Foo::Bar;

sub new { 
  my $class = shift;
  return bless {}, $class;
}

#...

package main;

my $foo = Foo::Bar->new();
print ref $foo;  # Foo::Bar

The overall scheme would be to replace your "require ..." with the contents of what you're requiring. There's more to it than that (BEGIN { } may be needed), and I'm not exactly sure what's involved. For sure, you'd want to automate it.

Here's an alternative: generate a single executable file where modules you depend on are packed inside it using PAR/pp

You've already got a few good answers. In addition, it is possible to make a module than can be run directly as a script.

package Foo;

__PACKAGE__->run(@ARGV) unless caller();

sub run {
    # Do stuff here if you are running the Foo.pm as
    # a script rather than using it as a module.
}

For additional details, see brian d foy's How a Script Becomes a Module.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top