在Perl脚本中分离配置数据和脚本逻辑

前端之家收集整理的这篇文章主要介绍了在Perl脚本中分离配置数据和脚本逻辑前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我发现以下反模式在我的Perl脚本中重复:脚本包含一些机器/设置特定的设置,我在线存储为脚本中的常量,而脚本的其余部分是通用的:
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. # machine specific settings at the start of the script.
  7. my $SETTING_1 = "foo";
  8. my @SETTING_2 = ("123","456");
  9. my $SETTING_3 = "something";
  10.  
  11. # general part of script follows.
  12. ...

这种模式在一台机器上运行时有点好,但是一旦我想将脚本分发到多台机器,麻烦就开始了,因为我必须保持跟踪,所以我不会在一般部分中用新的更新覆盖设置部分.

显然,正确的解决方案是具有一个通用脚本文件,并且读取一个特定于脚本运行的环境的配置文件.

我的问题是:您会推荐什么CPAN模块来解决这个问题?为什么?

解决方法

我最喜欢的是 Config::Std.我喜欢它处理 multi-linemulti-part配置值的方式.

变量可能是多值时必须小心:如果配置文件中存在单个值,它将以标量存储该值;如果存在多个值,您将获得一个数组引用.

我发现有两个配置文件是方便的:一个用于描述操作环境的值(在哪里可以找到库等),另一个用于用户修改的行为.

我也想写一个包装纸.例如(更新为包括自动生成的只读访问器):

  1. #!/usr/bin/perl
  2.  
  3. package My::Config;
  4. use strict; use warnings;
  5.  
  6. use Config::Std;
  7. use FindBin qw($Bin);
  8. use File::Spec::Functions qw( catfile );
  9.  
  10. sub new {
  11. my $class = shift;
  12. my ($config_file) = @_;
  13.  
  14. $config_file = catfile($Bin,'config.ini');
  15. read_config $config_file => my %config;
  16.  
  17. my $object = bless \%config => $class;
  18.  
  19. $object->gen_accessors(
  20. single => {
  21. install => [ qw( root ) ],},multi => {
  22. template => [ qw( dir ) ],);
  23.  
  24. return $object;
  25. }
  26.  
  27. sub gen_accessors {
  28. my $config = shift;
  29. my %args = @_;
  30.  
  31. my $class = ref $config;
  32.  
  33. {
  34. no strict 'refs';
  35. for my $section ( keys %{ $args{single} } ) {
  36. my @vars = @{ $args{single}->{$section} };
  37. for my $var ( @vars ) {
  38. *{ "${class}::${section}_${var}" } = sub {
  39. $config->{$section}{$var};
  40. };
  41. }
  42. }
  43.  
  44. for my $section ( keys %{ $args{multi} } ) {
  45. my @vars = @{ $args{multi}->{$section} };
  46. for my $var ( @vars ) {
  47. *{ "${class}::${section}_${var}" } = sub {
  48. my $val = $config->{$section}{$var};
  49. return [ $val ] unless 'ARRAY' eq ref $val;
  50. return $val;
  51. }
  52. }
  53. }
  54. }
  55.  
  56. return;
  57. }
  58.  
  59. package main;
  60.  
  61. use strict; use warnings;
  62.  
  63. my $config = My::Config->new;
  64.  
  65. use Data::Dumper;
  66. print Dumper($config->install_root,$config->template_dir);
  1. C:\Temp> cat config.ini
  2. [install]
  3. root = c:\opt
  4.  
  5. [template]
  6. dir = C:\opt\app\tmpl
  7. dir = C:\opt\common\tmpl

输出

  1. C:\Temp> g.pl
  2. $VAR1 = 'c:\\opt';
  3. $VAR2 = [
  4. 'C:\\opt\\app\\tmpl','C:\\opt\\common\\tmpl'
  5. ];

猜你在找的Perl相关文章