在perl5中,我曾经用’do(file)’来配置这样的配置文件:
---script.pl start --- our @conf = (); do '/path/some_conf_file'; ... foreach $item (@conf) { $item->{rules} ... ... ---script.pl end --- ---/path/some_conf_file start --- # arbitrary code to 'fill' @conf @conf = ( {name => 'gateway',rules => [ {verdict => 'allow',srcnet => 'gw',dstnet => 'lan2'} ] },{name => 'lan <-> lan2',rules => [ {srcnet => 'lan',dstnet => 'lan2',verdict => 'allow',dstip => '192.168.5.0/24'} ] },); ---/path/some_conf_file end ---
Larry Wall的“Programming Perl”也提到了这种方法:
But do FILE is still useful for such things as reading program
configuration files. Manual error checking can be done this way:
# read in config files: system first,then user for $file ("/usr/share/proggie/defaults.rc","$ENV{HOME}/.someprogrc") { unless ($return = do $file) { warn "couldn't parse $file: $@" if $@; warn "couldn't do $file: $!" unless defined $return; warn "couldn't run $file" unless $return; } }
优点:
>每次都不需要编写自己的解析器 – perl解析和
为您创建数据结构;
>更快/更简单:本机perl数据
结构/类型没有从外部格式转换的开销(如YAML);
>不需要操纵@INC来加载
某个地方的模块与模块作为conf文件进行比较;
>减少额外费用
代码与模块作为conf文件进行比较;
>“配置文件”的“语法”与perl本身一样强大;
>“ad hoc”格式;
缺点:
>没有隔离:我们可以从“配置”执行/销毁任何东西
文件”;
如何使用perl6获得相同的效果?
有没有办法在perl6中做得更好(没有缺点)并且没有解析自己的语法,语法,模块包括?
像“从文件中的文本表示加载哈希值或数组”之类的东西?
解决方法
您可以使用EVALFILE($file)(参考文档
http://doc.perl6.org/language/5to6-perlfunc#do).
正如你所指出的,使用EVALFILE有缺点,所以我不打算在那个方向添加任何东西:-)
这是一个示例配置文件:
# Sample configuration (my.conf) { colour => "yellow",pid => $*PID,homedir => %*ENV<HOME> ~ "/.myscript",data_source => { driver => "postgres",dbname => "test",user => "test_user",} }
这是一个使用它的示例脚本:
use v6; # Our configuration is in this file my $config_file = "my.conf"; my %config := EVALFILE($config_file); say "Hello,world!\n"; say "My homedir is %config<homedir>"; say "My favourite colour is %config<colour>"; say "My process ID is %config<pid>"; say "My database configuration is:"; say %config<data_source>; if $*PID != %config<pid> { say "Strange. I'm not the same process that evaluated my configuration."; } else { say "BTW,I am still the same process after reading my own configuration."; }