perl - 如何使用 Perl 作为配置文件的语言?
问题描述
我有一个应用程序,我想允许用户在 Perl 中指定配置文件。
我想到的类似于 PKGBUILD 在 Arch 中的使用方式:它是一个 Bash 脚本,它只是source
来自“makepkg”工具的 d。它包含变量和函数定义:
pkgbase=somepkg
pkgname=('somepkg')
pkgver=0.0.1
...
prepare() {
cd "${srcdir}/${pkgbase}-${pkgver}"
...
}
我想在 Perl 中做这样的事情。我想我正在寻找 Perl 版本source
,它可以读取文件、评估文件并将所有子例程和变量导入调用者的命名空间。使用 Bash 版本,我可以想象编写一个 PKGBUILD,它获取另一个 PKGBUILD,然后覆盖一个或两个变量;我希望这种“继承”也可以在我的 Perl 配置文件中实现。
Perl 的一个问题do
是它似乎将文件的变量和子例程放入单独的名称空间中。另外,我不知道如何覆盖真正的子例程,只有命名的匿名子例程。
这是一个版本,可以用来说明我想要做什么。它不是很优雅,但它演示了重写子例程和变量,以及调用先前定义的子例程:
$ cat test-override
#!/usr/bin/perl
use warnings;
use strict;
my @tables = qw(a b c);
my $print_tables = sub {
print join(", ", @tables), "\n";
};
eval(`cat "test-conf"`) or die "$@";
&$print_tables();
$ cat test-conf
@tables = qw(d e f);
my $old_print_tables = $print_tables;
$print_tables = sub {
warn "In test-conf \$print_tables\n";
&$old_print_tables();
}
$ ./test-override
In test-conf $print_tables
d, e, f
另一种方法是让配置文件返回一个散列,其中数据和子例程作为值。还有使用类和继承的选项。但是,我希望配置文件在语法上尽可能轻量级。
“do”的文档提到了在配置文件中使用 Perl 的可能性,所以我知道这个问题之前已经考虑过。是否有一个规范的例子说明如何以“用户友好”的方式做到这一点?
解决方案
您对您希望此“配置文件”执行的操作(将 subs 和变量导入调用者的命名空间、覆盖 subs、类、继承...)的描述听起来像是标准的 Perl 模块。所以使用标准的 Perl 模块。
请注意,这种方法有广泛的先例:标准cpan
命令行客户端将其配置存储在一个模块中,该模块位于~/.cpan/CPAN/MyConfig.pm
*nix 类型系统的默认路径中。当然,cpan
'sMyConfig.pm
是一个非常简单的示例,它只设置了 hashref $CPAN::Config
,但它没有理由不能做任何模块所做的所有其他事情。
但是做起来do
很简单。我怀疑你只是想多了:
$ cat test-override
#!/usr/bin/perl
use warnings;
use strict;
our @tables = qw(a b c);
sub print_tables {
print join(", ", @tables), "\n";
};
print_tables;
do "test-conf";
print_tables;
print "\@tables is @tables\n";
$ cat test-conf
@tables = qw(d e f);
sub print_tables {
print "print_tables from test_conf\n";
}
$ ./test-override
a, b, c
print_tables from test_conf
@tables is d e f
我所做的重要更改@tables
是将其从my
仅在当前范围和当前文件中可见的 更改our
为在同一个包中的任何位置都可见(或者如果它具有包名称,则从其他包中可见)。
但是print_tables
配置文件中的 my 不会调用 original print_tables
,而您在那个上不走运。因为只能有一个&main::print_tables
,替换它会完全覆盖原来的那个,不再存在。如果您希望能够覆盖它并且仍然能够调用原始声明,则需要将两个声明放入不同的包中,这意味着使用 OO Perl(这样您就可以多态地调用正确的)。
另请注意,use
具有与 相同的词法范围,这my
意味着您use strict; use warnings;
不会延续到 conf 文件中。您可以通过在我的版本中添加 来轻松演示这一点,此时它将生成警告。use warnings;
test-conf
Subroutine print_tables redefined
推荐阅读
- javascript - 如何从子组件中更新和删除元素数组并将其传递给 ReactJs 中的父组件
- sql - SQL自动过滤结果
- ios - 运行时缺少属性
- swift - 处理通过 NSViewRepresentable 嵌入的 NSTextView 中的键盘输入?(SwiftUI/MacOS)
- matlab - Matlab中气体动力学欧拉方程的最优控制
- c# - 数据库读取器在读取数据之前关闭
- python - Discord - 仅从 python 应用程序向不和谐通道发送消息(单向通信)
- ios - 通过 WKWebView 使用自定义本地存储字体
- rust - 如何在 rust 中创建匹配宏?
- python - 如何在 AWS EC2 Linux/UNIX 实例上部署 Flask 应用程序