tags:

views:

173

answers:

4

I have a Perl script that is getting big, so I want to break it out into multiple scripts. namely, I want to take out some large hash declarations and put them into another file. How do I get the original script to be able to see and use the variables that are now being declared in the other script?

This is driving me nuts because I haven't used Perl in a while and for the life of me can't figure this out

+10  A: 

You use modules. Or modulinos.

Make it a module that exports (optionally!) some variables or functions. Look up how to use the Exporter module.

Chris Lutz
i saw that but could swear there was some easier way. i might just be going nuts at the end of a long day...
John
@john: yes, there are other ways, but they violate Best Practices and so shall not be divulged here.
Ether
It's the most maintainable way, and the best way in the long run. If you have to, you can use the `do` function to run another Perl script, so you could put all your variable declarations in "myvars.pl" and then `do "myvars.pl"`, but if you do this, it's getting to the point where you should be using a module.
Chris Lutz
@Ether - Oops! Sorry I divulged them. You're right, of course, they shouldn't be used.
Chris Lutz
+11  A: 

Use a module:

package Literature;

our %Sidekick = (
  Batman => "Robin",
  Bert   => "Ernie",
  Don    => "Sancho",
);

1;

For example:

#! /usr/bin/perl

use Literature;

foreach my $name (keys %Literature::Sidekick) {
  print "$name => $Literature::Sidekick{$name}\n";
}

Output:

$ ./prog 
Bert => Ernie
Batman => Robin
Don => Sancho
Greg Bacon
I would argue that Bert was Ernie's sidekick, but otherwise a fine example.
Robert P
With a little Exporter magic we could even `use Literature qw(Sidekicks);` and not have to use the full package name. It'd make the package more complex, but be worth it in the end.
Chris Lutz
Don't forget the 1! It's important! I know you have it gbacon, but it's one that bites people.
Jeff B
Oof, exporting variables? Doesn't perldoc warn against doing that? :) http://perldoc.perl.org/Exporter.html#What-not-to-Export
Robert P
@Robert P - The OP wants to share variable names between Perl scripts. Therefore, his code is going to be using potentially volatile variables from a module whether he exports them or not. I agree it may not be the best idea, but there's nothing explicitly wrong with it if you're careful.
Chris Lutz
Exporting *by default* should be avoided. There's nothing wrong with explicit exports.
friedo
@Jeff: Actually, in this case, the 1 isn't needed. Ending with a 1 just ensures that the last statement in the module will return a true value. Assignments return the assigned value, so "our %Sidekick = (...)" is already a true value. (Always use the 1 anyhow, but never forget why it's there.)
Dave Sherohman
+3  A: 

As an addition to the other "use a module" suggestions, if you plan on reusing the module a lot, you will want to get this installed into either your site library (usually under ...(perl install folder)...\site\lib.

If not (perhaps, it has limited reusability outside the script), you can keep it in the directory with your script and import it like so:

use lib './lib'; # where ./lib is replaced with wherever the module actually is.
use MyModule;
Robert P
+5  A: 

Yet another suggestion to use a module.

Modules are not hard to write or use. They just seem hard until you write one. After the first time, it will be easy. Many, many good things come from using modules--encapsulation, ease of testing, and easy code reuse to name a few.

See my answer to a similar question for an example module, with exported functions.

Also, some very smart people in the Perl community like modules so much that they advocate writing apps as modules--they call them modulinos. The technique works well.

So, in conclusion, try writing a module today!

daotoad