Ideally you'd copy the file so that you can edit it, then turn it into a module so to use it nicely.
But if for some reason this isn't feasible here are your options.
If that hash is the only thing in the file, "load" it using do† and assign to a hash
use warnings;
use strict;
my $file = './read_this.pl'; # the file has *only* that one hash
my %hash = do $file;
This form of do
executes the file (runs it as a script), returning the last expression that is evaluated. With only the hash in the file that last expression is the hash definition, precisely what you need.
If the hash is undeclared, so a global variable (or declared with our
), then declare as our
a hash with the same name in your program and again load the file with do
our %hash_name; # same name as in the file
do $file; # file has "%hash" or "our %hash" (not "my %hash")
Here we "pick up" the hash that is evaluated as do
runs the file by virtues of our
If the hash is "lexical", declared as my %hash
(as it should be!) ... well, this is bad. Then you need to parse the text of the file so to extract lines with the hash. This is in general very hard to do, as it amounts to parsing Perl. (A hash can be built using map
, returned from a sub as a reference or a flat list ...) Once that is done you eval
the variable which contains the text defining that hash.
However, if you know how the hash is built, as you imply, with no ()
anywhere inside
use warnings;
use strict;
my $file = './read_this.pl';
my $content = do { # "slurp" the file -- read it into a variable
local $/;
open my $fh, '<', $file or die "Can't open $file: $!";
<$fh>;
};
my ($hash_text) = $content =~ /\%hash_name\s*=\s*(\(.*?\)/s;
my %hash = eval $hash_text;
This simple shot leaves out a lot, assuming squarely that the hash is as shown. Also note that this form of eval carries real and serious security risks.
†
Files are also loaded using require. Apart from it doing a lot more than do
, the important thing here is that even if it runs multiple times require
still loads that file only once. This matters for modules in the first place, which shouldn't be loaded multiple times, and use indeed uses require
.
On the other hand, do
does it every time, what makes it suitable for loading files to be used as data, which presumably should be read every time. This is the recommended method. Note that require
itself uses do
to actually load the file.
Thanks to Schwern for a comment.