I have an application where I would like to allow users to specify configuration files in Perl.
What I have in mind is similar to how PKGBUILD is used in Arch: it is a Bash script, which is simply source
d from the "makepkg" tool. It contains variable and function definitions:
pkgbase=somepkg
pkgname=('somepkg')
pkgver=0.0.1
...
prepare() {
cd "${srcdir}/${pkgbase}-${pkgver}"
...
}
I would like to do something like this in Perl. I guess I'm looking for a Perl version of source
, which can read a file, evaluate it, and import all the subroutines and variables into the namespace of the caller. With the Bash version, I could conceivably write a PKGBUILD which sources another PKGBUILD and then overrides one or two variables; I want this kind of "inheritance" to be possible in my Perl config files as well.
One problem with Perl's do
is that it seems to put the file's variables and subroutines into a separate namespace. Also, I can't figure out how to override true subroutines, only named anonymous ones.
Here's a version that may serve to illustrate what I want to do. It is not very elegant, but it demonstrates overriding both subroutines and variables, as well as calling a previously-defined subroutine:
$ 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
Another way to do this would be to let the configuration file return a hash, with data and subroutines as values. There is also the option of using classes and inheritance. However, I want the configuration files to be as light-weight as possible, syntactically.
The documentation for "do" mentions the possibility of using Perl in configuration files, so I know this problem has been considered before. Is there a canonical example of how to do it in a "user-friendly" manner?