理想情况下,您会复制文件以便编辑它,然后将其转换为模块以便很好地使用它。
但是,如果由于某种原因这不可行,这是您的选择。
如果该散列是文件中唯一的内容,则使用do † “加载”它并分配给散列
use warnings;
use strict;
my $file = './read_this.pl'; # the file has *only* that one hash
my %hash = do $file;
这种形式的do
执行文件(将其作为脚本运行),返回最后一个被评估的表达式。只有文件中的哈希,最后一个表达式就是哈希定义,这正是您所需要的。
如果散列未声明,则为全局变量(或用 声明our
),然后our
在程序中声明为具有相同名称的散列并再次加载文件do
our %hash_name; # same name as in the file
do $file; # file has "%hash" or "our %hash" (not "my %hash")
在这里,我们“拾取”评估为do
运行文件的哈希值
如果哈希是 "lexical",则声明为my %hash
(应该如此!)......好吧,这很糟糕。然后你需要解析文件的文本以便提取带有哈希的行。这通常很难做到,因为它相当于解析 Perl。(可以使用 构建散列map
,从 sub 作为引用或平面列表返回...)一旦完成,您eval
就可以使用包含定义该散列的文本的变量。
但是,如果您知道哈希是如何构建的,正如您所暗示的那样,()
里面没有任何地方
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;
这个简单的镜头遗漏了很多,假设散列如图所示。另请注意,这种形式的eval具有真实且严重的安全风险。
†
文件也使用require加载。除了它做的很多以外do
,这里重要的是即使它运行多次require
仍然只加载该文件一次。这首先对模块很重要,它不应该被多次加载,并且 确实使用usesrequire
。
另一方面,do
每次都这样做,是什么使它适合加载文件用作数据,大概应该每次都读取。这是推荐的方法。请注意,require
它本身用于do
实际加载文件。
感谢施韦恩的评论。