78

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.

Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133
Zain Rizvi
  • 23,586
  • 22
  • 91
  • 133
  • 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? – daotoad Nov 11 '09 at 01: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 – Zain Rizvi Nov 11 '09 at 20:14

10 Answers10

78

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.

daotoad
  • 26,689
  • 7
  • 59
  • 100
  • 3
    Check out Sub::Exporter it is all the rave! http://search.cpan.org/~rjbs/Sub-Exporter-0.982/lib/Sub/Exporter.pm – Evan Carroll Nov 11 '09 at 06:35
  • 7
    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'); – Zain Rizvi Nov 11 '09 at 20:16
  • 1
    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? – joejoeson Apr 16 '10 at 15:00
  • 2
    @Jeremy, check out http://stackoverflow.com/questions/2526804/how-is-perls-inc-constructed-aka-what-are-all-the-ways-of-affecting-where-per – daotoad Apr 16 '10 at 15:32
  • 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 – yonetpkbji Sep 05 '13 at 13:00
  • @perl-user, it is possible, but generally it is better to use accessors to manage the variables. The most straight forward way to share a variable is to declare it with `our` in your module. You can then access it using a fully qualified package + variable name: `package Foo; our @bar = 1..5;` Access as `@Foo::bar`. – daotoad Sep 13 '13 at 02:35
  • @daotoad I think its important to say in this answer that if you are going to have the Foo.pm in the same directory as your perl script that you need to add: use File::Basename; use lib dirname (__FILE__); Before trying to import Foo – joshlk Mar 20 '14 at 10:39
  • @Josh, the current directory is in `@INC` by default. BTW, for searching for directories to add to my @INC, I find tye's File::FindLib meets my needs better than anything else out there. https://metacpan.org/pod/File::FindLib – daotoad Mar 25 '14 at 20:17
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.
martin clayton
  • 76,436
  • 32
  • 213
  • 198
  • 4
    This one is more directly comparable to C's #include from what I can tell, and is exactly what I needed. – Herms Apr 28 '10 at 14:35
  • `A package allows you to expose some functions, but hide others. With no packages, all functions are visible.` How do we do this? – N3Xg3N Sep 26 '14 at 06:51
10

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

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
8

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

Daniel Plaisted
  • 16,674
  • 4
  • 44
  • 56
6

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
sdaau
  • 36,975
  • 46
  • 198
  • 278
  • 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? – iJames Dec 24 '19 at 06:28
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 ;-)

Benj
  • 31,668
  • 17
  • 78
  • 127
4

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

aartist
  • 3,145
  • 3
  • 33
  • 31
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;

Community
  • 1
  • 1
kakyo
  • 10,460
  • 14
  • 76
  • 140
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

Able Mac
  • 846
  • 7
  • 8
-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;

}

  • The server-side code will handle processing the file using the `includefile` subroutine we discussed earlier in Perl: ```html Include File Form

    Include File Form


    – ChiMoHe Aug 06 '23 at 13:53
  • 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. – ChiMoHe Aug 06 '23 at 13:53
  • 1
    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. – ChiMoHe Aug 06 '23 at 13:53