83

This seems like a really simple question but somehow my Google-Fu failed me.

What's the syntax for including functions from other files in Perl? I'm looking for something like C's #include "blah.h"

I saw the option for using Perl modules, but that seems like it'll require a not-insignificant rewrite of my current code.

2
  • 8
    Willy-nilly inclusion of scripts into each other is asking for pain. The difference between a module and a script codewise is very slight, but the encapsulation is much better. What specific things make you think a major rewrite will be required to use modules? Commented Nov 11, 2009 at 1:17
  • 3
    The guides I was looking at online made creating and adding modules look like a much more complicated task than it actually was. Thanks for showing me its simplicity Commented Nov 11, 2009 at 20:14

10 Answers 10

83

Use a module. Check out perldoc perlmod and Exporter.

In file Foo.pm

package Foo;
use strict;
use warnings;
use Exporter;

our @ISA= qw( Exporter );

# these CAN be exported.
our @EXPORT_OK = qw( export_me export_me_too );

# these are exported by default.
our @EXPORT = qw( export_me );

sub export_me {
    # stuff
}

sub export_me_too {
    # stuff
}

1;

In your main program:

use strict;
use warnings;

use Foo;  # import default list of items.

export_me( 1 );

Or to get both functions:

use strict;
use warnings;

use Foo qw( export_me export_me_too );  # import listed items

export_me( 1 );
export_me_too( 1 );

You can also import package variables, but the practice is strongly discouraged.

Sign up to request clarification or add additional context in comments.

8 Comments

Check out Sub::Exporter it is all the rave! search.cpan.org/~rjbs/Sub-Exporter-0.982/lib/Sub/Exporter.pm
Additionally, if you're not installing the module in one of the default locations for perl modules, just add this before the "use Foo;" line: use lib ('C:/Module/Location');
Lets say I have libs from the default location and I want to use a module that is located in the local directory because it is really only used by the current app and the module was created to better organize the script. will the use lib line tell perl to only look at the location I specify for all module or does it add to the lib path that perl searches?
Is it possible to make variables global, across the main script and also the modules that you create? If so, how would it be done as I am having some trouble? thanks a lot
|
55

Perl require will do the job. You will need to ensure that any 'require'd files return truth by adding

1;

at the end of the file.

Here's a tiny sample:

$ cat m1.pl 
use strict;
sub x { warn "aard"; }
1;

$ cat m2.pl 
use strict;
require "m1.pl";
x();

$ perl m2.pl 
aard at m1.pl line 2.

But migrate to modules as soon as you can.

EDIT

A few benefits of migrating code from scripts to modules:

  • Without packages, everything occupies a single namespace, so you may hit a situation where two functions from separate files want the same name.
  • A package allows you to expose some functions, but hide others. With no packages, all functions are visible.
  • Files included with require are only loaded at run time, whereas packages loaded with use are subject to earlier compile-time checks.

2 Comments

This one is more directly comparable to C's #include from what I can tell, and is exactly what I needed.
A package allows you to expose some functions, but hide others. With no packages, all functions are visible. How do we do this?
12

Also, do 'file.pl'; will work, but modules are the better solution.

Comments

8

I believe you are looking for the require or use keywords.

Comments

7

I know the question specifically says "functions", but I get this post high up in search when I look for "perl include", and often times (like now) I want to include variables (in a simple way, without having to think about modules). And so I hope it's OK to post my example here (see also: Perl require and variables; in brief: use require, and make sure both "includer" and "includee" files declare the variable as our):

$ perl --version

This is perl, v5.10.1 (*) built for i686-linux-gnu-thread-multi ...

$ cat inc.pl
use warnings;
use strict;

our $xxx = "Testing";

1;

$ cat testA.pl 
use warnings;
use strict;

require "inc.pl";
our $xxx;

print "1-$xxx-\n";
print "Done\n";

$ perl testA.pl 
1-Testing-
Done


$ cat testB.pl 
use warnings;
use strict;

our $xxx;
print "1-$xxx-\n";

$xxx="Z";
print "2-$xxx-\n";

require "inc.pl";

print "3-$xxx-\n";
print "Done\n";

$ perl testB.pl 
Use of uninitialized value $xxx in concatenation (.) or string at testB.pl line 5.
1--
2-Z-
3-Testing-
Done

1 Comment

EXACTLY what I was looking for. And nobody's suggested that it's not a good idea? So I'm thinking that means it's still a good way to provide a set of values to multiple perl scripts?
4

You really should look into perl modules however, for a quick hack you could always run "perl -P" which runs your perl script through the C pre-processor. That means you can do #include and friends....

Only a quick hack though, beware ;-)

Comments

4

What are you looking for is 'require file.pl', but what you should be looking at is 'use module'.

Comments

3

The above answers all ignored the client part: How to import the module.

See the accepted answer here: How do I use a Perl module from a relative location?

Without the trick in this answer, you'll have plenty of trouble trying to get the module path right when you use $mymodule;

Comments

1

require is roughly equivalent to include. All of the namespace benefits can be achieved in a required perl script just like a perl module. The "magic" is in what you put in the script.

The only caveat to including a script is you need to return 1; at the end of the script, or perl says it failed, even if you haven't called anything in the script.

require "./trims.pl"

Then in your perl script it can be as simple as:

#!/usr/bin/perl

#use "trims.pl";


sub ltrim { my $s = shift; $s =~ s/^\s+//;       return $s };
sub rtrim { my $s = shift; $s =~ s/\s+$//;       return $s };
sub  trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
return 1;

This example removes white space from the left, right or both ends of the input string. $string = trim($string);

The comment of #use "trims.pl" can be pasted in your perl script, uncommented (remove the #) and perl will look in the same folder your script is in to find trims.pl and this puts the functions ltrim(), rtrim(), and trim() in the global name space, so you can't have those function names in any other global name space or perl will detect a conflict and stop the execution.

To learn more about controlling name spaces, look into "perl packages & modules" package Foo;

https://perldoc.perl.org/functions/package

Comments

-1

Back in 2006 I wrote a Perl subroutine called includelife. I thought you would appreciate it. This year I download a ChatGPT 3.5 and had the app write white paper for the subroutine.

sub includefile {
my $fname = shift;
my $file;

# Remove potentially harmful               
characters from the file name
$fname =~ s/([\&;\`'\|\"*\?\~\^\(\)\
[\]\{\}\$\n\r])//g;

# Open the file for reading
if (!fopen(INCLUDE, $fname)) {
    return '[an error occurred while processing this directive]';
}

# Read the content of the file and 
store it in $file
$file = join('', <INCLUDE>);

# Close the file
fclose(INCLUDE);

return $file;

}

4 Comments

The server-side code will handle processing the file using the includefile subroutine we discussed earlier in Perl: ```html <!DOCTYPE html> <html> <head> <title>Include File Form</title> </head> <body> <h2>Include File Form</h2> <form action="/process_file" method="post"> <!-- Replace "/process_file" with the URL to handle form submission on the server-side --> <label for="filename">Enter File Name:</label> <input type="text" id="filename" name="filename" required><br> <input type="submit" value="Submit"> </form> </body> </html>
Save the above code in an HTML file, e.g., "includefile_form.html," and open it in a web browser. The form will have a text input field where users can enter the file name they want to process using the includefile subroutine. When they click the "Submit" button, the form data will be sent to the URL specified in the action attribute of the form element. On the server-side (e.g., using Perl), you need to handle the form submission at the specified URL ("/process_file") and retrieve the value of the filename input field.
You can then use the includefile subroutine to process the file with the provided file name and return the results accordingly. Remember to sanitize and validate the user input before processing the file to ensure security.
Is not include directive leads to a lot of problems? How can you handle bidirectional include? And what size of the output program will be if you use import base file from the different files?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.