2

我有一个包(实际上只有一个子程序),我经常使用它来解析配置文件等。基本上它看起来像这样:

sub get_settings {
        my %config;
        my $config = 'path...';

        unless(-r $config) {
                die("Couldn't read config");
        }
        open CONFIG, '<', $config or die $!;
        while(<CONFIG>) {
                next if (($_ eq "\n") or /^\;/);
                chomp;
                my($setting, $value) = split(/=/, $_);
                $config{$setting} = $value;
        }
        return %config;
}

非常基本,但我想知道如何(以及是否)这可以/应该重写为OOP?真的只是为了学习,从来没有见过何时以及为什么使用bless。=)

谢谢!

4

3 回答 3

2

这是(希望如此!)基于 OO 的配置抽象的简单示例,使用:

注意。您可以使用其他模块,甚至可以使用自己的模块。以下仅作为一般示例。

RoomConfig.pm

package RoomConfig;
use Moose;
with 'MooseX::SimpleConfig';

has doors   => (is => 'rw', isa => 'Int', required => 1);
has windows => (is => 'rw', isa => 'Int', default  => sub {0});

1;

以上就是我们的 OO 配置类。一切都被整齐地声明,因此您清楚地知道配置选项可用且有效,即。它的自我记录。

因此,从配置文件创建一个room将是:

use RoomConfig;

my $box_room = RoomConfig->new_with_config( configfile => 'box_room.yaml' );

因为它是一个类,所以我也可以在room没有配置文件的情况下实例化 a:

my $cupboard       = RoomConfig->new( doors => 1 );
my $utility_room   = RoomConfig->new( doors => 2 );
my $master_bedroom = RoomConfig->new( 
    doors      => 1,
    windows    => 2,   # dual aspect
);

此外,通过这些特定模块,我们可以获得如下额外功能:

# below throws exception because room must have a door!
my $room_with_no_door_or_window = RoomConfig->new; 

因此,我的配置可以很容易地来自配置文件或通过设置属性。


我们可以通过为不同类型扩展我们的配置来走得更远rooms

浴室配置.pm

package BathRoomConfig;
use Moose;
extends 'RoomConfig';

has loos  => (is => 'rw', isa => 'Int', default  => sub {0});
has sinks => (is => 'rw', isa => 'Int', default  => sub {0});
has baths => (is => 'rw', isa => 'Int', default  => sub {1});

1;

如果我们使用这个配置(bathroom.yaml):

doors:  1
windows:    1
bath:   1
loos:   1
sinks:  2

然后你可以这样做:

use BathRoomConfig;

my $upstairs_bathroom = BathRoomConfig->new_with_config( 
    configfile => 'bathroom.yaml' 
);

my $closet_room = BathRoomConfig->new_with_config( 
    configfile => 'bathroom.yaml',
    baths      => 0,
    sinks      => 1,
    windows    => 0,
);

请注意,$closet_room它同时使用了配置文件和设置属性。

另请注意,如果我的配置文件没有doors(即必需的属性),那么它会在new_with_config.


最后,我们可能会发现自省我们定义的配置类很方便:

use RoomConfig;

say "RoomConfig provides the following options:";

for my $attr (RoomConfig->meta->get_attribute_list) {
    next if $attr eq 'configfile';
    say '-> ', $attr;
}


现在没有什么能阻止您在标准配置包中实现大部分内容,所以归根结底,它只是课程的马!

然而,使用 OO 可以轻松管理所有这一切,并且这些已经编写的模块提供的功能具有很大的优势,尤其是在更大的项目中。

于 2010-08-25T13:15:39.363 回答
1

该问题的答案与您使用该软件包的程序有关,而不是与软件包本身有关。

如果这是一个非常大的基于 OOP 的应用程序/脚本,那么 OOP 肯定是有意义的,因为这是客户所期望的(应用程序和编写这些应用程序/脚本的人)。此外,命令式样式库也像大拇指一样突出并产生复杂性。

相反,如果包用在较短的命令式脚本中,那么 OOP 接口将与客户的期望相冲突(即脚本+开发它们的人)。

也许您正在方法之间迁移(例如,脚本变得庞大而笨拙,需要更好地组织,可能使用 OOP)在这种情况下,设置/配置类是一个很好的起点,因为它们往往被很好地分开并且有明确的责任线。

简而言之:在使用包的地方做最有意义的事情。

于 2010-08-25T09:08:46.367 回答
0

您可以查看 CPAN 上模块的源代码。例如Config::General应该回答你的问题......

于 2010-08-25T10:05:00.297 回答