Embedding private .pm files into a script

H

Haakon Riiser

I keep my own little library of Perl routines in a directory
separate from the stuff that came with Perl itself and CPAN,
and I've put this directory in PERL5LIB. This is sufficient for
programs that only I use, but when friends and co-workers ask
for a copy of one of my scripts, it would be nice if I could just
give them a single file that contains everything they need.

I have looked at PAR, but what it does is overkill. I don't need
it to bundle every single dependancy to create a huge stand-alone
executable. Only the modules from my personal library needs to
be embedded into the resulting script. I see that pp has the -X
option to exclude a named module, but what I want is to exclude
everything except the stuff stored in a certain directory tree.
As far as I can tell, PAR can't do this.

Is there an easy way to accomplish what I want? I could embed
the required modules by hand, but that's too much work. :)
 
A

A. Sinan Unur

I keep my own little library of Perl routines in a directory
separate from the stuff that came with Perl itself and CPAN,
and I've put this directory in PERL5LIB. This is sufficient for
programs that only I use, but when friends and co-workers ask
for a copy of one of my scripts, it would be nice if I could just
give them a single file that contains everything they need.

See

perldoc -q lib
perldoc lib
perldoc FindBin

NAME
FindBin - Locate directory of original perl script

SYNOPSIS
use FindBin;
use lib "$FindBin::Bin/../lib";

or

use FindBin qw($Bin);
use lib "$Bin/../lib";

So, put your scripts in a directory, and put your packages in a
subdirectory of that. Then zip everything up. Give them the zip file.

Sinan
 
H

Haakon Riiser

[A. Sinan Unur]
See

perldoc -q lib
perldoc lib
perldoc FindBin

NAME
FindBin - Locate directory of original perl script

SYNOPSIS
use FindBin;
use lib "$FindBin::Bin/../lib";

or

use FindBin qw($Bin);
use lib "$Bin/../lib";

So, put your scripts in a directory, and put your packages in a
subdirectory of that. Then zip everything up. Give them the zip file.

Thanks for the tip, but I'd prefer not having to reorganize my
directories.

I think I'll just write a simple script to convert all 'use'
declarations that refer to my private modules by a simple

package Private::Foo;
<contents of Private/Foo.pm>
package main;

This works as long as I don't include my modules in a fancy way
(such as loading them on demand, etc.)
 
A

Ala Qumsieh

Haakon said:
[A. Sinan Unur]

See

perldoc -q lib
perldoc lib
perldoc FindBin

NAME
FindBin - Locate directory of original perl script

SYNOPSIS
use FindBin;
use lib "$FindBin::Bin/../lib";

or

use FindBin qw($Bin);
use lib "$Bin/../lib";

So, put your scripts in a directory, and put your packages in a
subdirectory of that. Then zip everything up. Give them the zip file.


Thanks for the tip, but I'd prefer not having to reorganize my
directories.

What's wrong with a simple:

use lib '/path/to/your/module/dir';

?

--Ala
 
H

Haakon Riiser

[Ala Qumsieh]
What's wrong with a simple:

use lib '/path/to/your/module/dir';

?

I can think of at least three things:

(1) I don't want the script to search in a specific location.
I could use relative paths, but that would still be a problem if
someone decides to move the executable to another bin directory.

(2) If someone asks for a script 'foo', I want to be able to give
that to him without having to manually determine the module
dependencies and then copying all of the required files.

(3) I don't want other people to have to deal with the clutter
of separate modules. A single script should be enough for these
trivial things I'm talking about here.

But nevermind -- simply substituting the 'use' statement with the
contents of the respective module is good enough in this case, and
automating that task is simple.
 
A

Anno Siegel

Haakon Riiser said:
[A. Sinan Unur]
See

perldoc -q lib
perldoc lib
perldoc FindBin

NAME
FindBin - Locate directory of original perl script

SYNOPSIS
use FindBin;
use lib "$FindBin::Bin/../lib";

or

use FindBin qw($Bin);
use lib "$Bin/../lib";

So, put your scripts in a directory, and put your packages in a
subdirectory of that. Then zip everything up. Give them the zip file.

Thanks for the tip, but I'd prefer not having to reorganize my
directories.

I think I'll just write a simple script to convert all 'use'
declarations that refer to my private modules by a simple

package Private::Foo;
<contents of Private/Foo.pm>
package main;

This works as long as I don't include my modules in a fancy way
(such as loading them on demand, etc.)

The "package"-statements are presumably already part of Private::Foo.
However, the contents should go into a block of their own so that
file-scoped lexicals in Private/Foo.pm don't leak out into your
lexical space. Also, if you want to put the module after code that
uses it, that block must be a BEGIN block. Thirdly, in case the module
has an ->import method, it should be called with the parameters that
would otherwise go in the "use" statement.

So, to replace the statement

use Private::Foo qw( fie foe fum);

one should use two BEGIN blocks:

BEGIN {
<contents of Private/Foo.pm>
}
BEGIN {
Private::Foo->import( qw( fie foe fum);
}

That should cover most cases.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,609
Members
45,253
Latest member
BlytheFant

Latest Threads

Top